简体   繁体   中英

Form submission before route leave in vue js

I am new to VueJs and I'm stuck in a problem. I am creating a form and want to show a alert dialog with message "you might lose the data, please save the data before you leave." and when i click on yes it should submit the form and change the the route.

I know that we can do this with beforeRouteLeave(to, from, next) but how do i submit the form before route leave on clicking yes in alert box?

在此处输入图像描述 in above image my route is /create when

handleArticleSubmit() {
    // Collect form data
    let formData = new FormData();

    // Start Button Loading
    this.isSubmittingArticle = true;
    axios
      .post("/articles", formData, {
        headers: {
          "Content-Type": "multipart/form-data"
        }
      })
      .then(res => {
        // Stop button loading
        this.isSubmittingArticle = false;
        // Show alert message
        this.snackbar = {
          isVisible: true,
          color: "success",
          text: "Article submited successfully"
        };

      })
      .catch(error => {
        // Stop button loading
        this.isSubmittingArticle = false;
        // Show alert
          // Show alert message
          this.snackbar = {
            isVisible: true,
            color: "error",
            text: error
          };
        }
      });
  }
},

above mentioned code saves the article i want to change the route if form submits with all validation validation (like blank, number etc.) if not then should not change the route. thanks right now i am using this code to change route:

beforeRouteLeave(to, from, next) {
  const answer = window.confirm(
    "you might lose the data, please save the data before you leave."
  );
  if (answer) {
    this.handleArticleSaveDraft();
    next();
  } else {
    next(false);
}

thanks.

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)
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM