[Vuejs]-Form submission before route leave in vue js

1👍

Edited comment

You need to take care of these:

  1. Promisify the handleArticleSubmit method
  2. Make beforeRouteLeave asynchronous
  3. Use try/cache to check the promise, so if it is rejected (form has an error) page does not change, you can also log the error if you want.

See how it is implemented below:


methods: {
    handleArticleSubmit() {
        return new Promise((resolve, reject) => {   // 1. Promisify the method                  
            let formData = new FormData() 
            this.isSubmittingArticle = true 
            axios
            .post("/articles", formData, {
                headers: {
                    "Content-Type": "multipart/form-data"
                }
            })
            .then(res => {        
                this.isSubmittingArticle = false         
                this.snackbar = { 
                    isVisible: true,
                    color: "success",
                    text: "Article submited successfully"
                }
                resolve() // Resolve the promise (all is good)
            })
            .catch(error => {        
                this.isSubmittingArticle = false         
                this.snackbar = { // Show alert message
                    isVisible: true,
                    color: "error",
                    text: error
                }   
                reject(error) // Reject it when error happens
            })
        })
    }
},
async beforeRouteLeave (to, from, next) { // 2. Make this async
    let answer = window.confirm("you might lose the data, please save the data before you leave.")
    if (answer) {
        // 3. Try/catch to confirm the resolve
        try{ 
            await this.handleArticleSubmit() 
            // Resolved
            next() 
        } catch (err) { // Rejected
            next(false)
            log(err)
        }                
    } else {
        next(false)
    }
}

Old comment

This is specifically mentioned in the Navigation Guards as Leave Guard, in Vue Router documentation.

beforeRouteLeave (to, from, next) {
  const answer = window.confirm('you might lose the data, please save the data before you leave.')
  if (answer) {
    this.submit() // Submit your form here however you want
    next()
  } else {
    next(false)
  }
}

Or if you have a custom modal system, make it asynchronous, and make sure your modal is returning a promise:

async beforeRouteLeave (to, from, next) {
  const answer = await this.openModal()
  if (answer) {
    this.submit() // Submit your form here however you want
    next()
  } else {
    next(false)
  }
}

Leave a comment