vee-validate: Clear errors after form submition

Versions:

  • VueJs: 2.1.7
  • Vee-Validate: 2.0.0-beta.18

Description:

Once I submit the form I clear the fields and I want to clear the errors as well, but I’m having a hard time trying to do that.

Steps To Reproduce:

Form:

<form role="form" class="form-horizontal" @submit.prevent="persistData">
            <legend>Supervisor & Deputy Requests</legend>

            <div class="form-group">
                <label for="requesttype" class="col-sm-2 control-label">Request type</label>
                <div class="col-sm-10">
                    <select v-model="form.requesttype" name="form.requesttype" id="requesttype" class="form-control"
                            data-vv-rules="required" v-validate.initial="form.requesttype">
                        <option value=""></option>
                        <option value="Option 01">Option 01</option>
                        <option value="Option 02">Option 02</option>
                    </select>
                    <span v-show="errors.has('form.requesttype')" class="text-danger">This field is required</span>
                </div>
            </div>
            <div class="form-group">
                <label for="userid" class="col-sm-2 control-label">User ID</label>
                <div class="col-sm-10">
                    <input v-model="form.userid" name="form.userid" type="text" class="form-control" id="userid"
                           data-vv-rules="required"
                           v-validate.initial="form.userid">
                    <span v-show="errors.has('form.userid')" class="text-danger">This field is required</span>
                </div>
            </div>
            <div class="form-group">
                <label for="requestdescription" class="col-sm-2 control-label">Request description</label>
                <div class="col-sm-10">
                    <textarea v-model="form.requestdescription" name="form.requestdescription" class="form-control"
                              id="requestdescription" cols="30"
                              rows="10" data-vv-rules="required"
                              v-validate.initial="form.requestdescription"></textarea>
                    <span v-show="errors.has('form.requestdescription')"
                          class="text-danger">This field is required</span>
                </div>
            </div>

            <button type="submit" class="btn btn-primary pull-right">Submit</button>
        </form>

Persist data method:

                let self = this
                // Validate All returns a promise and provides the validation result.
                this.$validator.validateAll().then(success => {
                    if (!success) {
                        // handle error
                        console.log('Error!')
                        return
                    }
                    axios.post('/static/api/SupervisorDeputyRequest/persistdata.php', queryString.stringify(self.form))
                        .then(res => {
                            self.form = {
                                requesttype: '',
                                userid: '',
                                requestdescription: ''
                            }
                        })

I want to clear the errors in the AJAX callback. This code is in a .vue file and vee-validate is being imported in the main.js file.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 27 (8 by maintainers)

Most upvoted comments

Hey, I was having issues with clearing form inputs and resetting the errors much like a few here. I’d basically set inputs to null on submit and then run this.$validator.reset(), it didn’t work.

The thing you have to remember is javascript is naturally asynchronous so, when you fire a function it’s running all the code at the same time, or attempting to, and that’s my rough understanding.

SO what I did was run an async function :

const clear = async () => {
    this.contact.firstName = null
    this.contact.lastName = null
    this.contact.email = null
    this.contact.message = null
}

And then call it that function. After it has completed I call the rest:

clear().then(() => {
    this.$validator.reset()
})

And it works for me. Hopefully that helps someone else.

have you tried:

this.errors.clear();

http://vee-validate.logaretm.com/api#error-bag

@burzum errors.clear isn’t enough, as it doesn’t reset the validator state like flags and does not respect Vue ticks, use validator.reset instead:

https://jsfiddle.net/logaretm/2rrbzyek/

In my case, i forgot to add the scope of the form i wanted to reset the errors for. this.errors.clear('my-scope') did the trick. Just fyi.

I used Promise.prototype.then() and worked for me.

I created a method called clear for clear all inputs and other called createMessage for submit:

  methods: {
       clear () {
          this.email = ''
          this.message = ''
          this.subject = ''
        }
        createMessage: function (event) {
            this.$validator.validateAll().then(function (result) {
               if (result) {
                  ...Your Mutation...

                    new Promise(function (resolve, reject) {
                        resolve('Reset Form!')
                        that.clear()
                    }).then(() => {
                       that.$validator.reset()
                    })
              }//if
          )}//validator
      }//createMessage
  }//methods

Just stumbled upon this thread when a friend asked me for help. I’d recommend you guys read more about Vue’s reactivity system and async update queue in particular.

The gist is that model changes are not flushed immediately when you change a particular model property. Changes are batched and deferred to the next tick for optimal performance. Vue provides nextTick hook that allows you to execute code right after the reconciliation had been performed. It’s probably a better idea than using setTimeout directly because it is a publicly documented API which will always yield the best and most reliable results.

EDIT: Polished the text and reinforced the reasoning.

I had to modify the code provided by @devanflaherty to basically wait for two event loop iterations. I reset the data, waited for nextTick, resolved and waited for another nextTick in the then callback. Code below:

methods:{
  clearFormData () {
    return new Promise(resolve => {
      Object.assign(this.$data, this.$options.data.call(this));
      this.$nextTick().then(() => resolve());
    });
  },
  resetForm () {
    return new Promise(resolve => {
      this.clearFormData().then(() => {
        this.$nextTick().then(() => {
          this.$validator.reset();
          this.errors.clear();
          resolve();
        });
      });
    });
  }
}

Not the most performant solution, but it seems to be a stable stopgap for the moment.

Also, FYI @dschreij, notice the line where I reset the data in the component. Using Object.assign(this.$data, this.$options.data.call(this)); will reset the components data to its default values. Its a useful shorthand way of doing it.

Got a little more info on this. I have configured vee-validate with this setting:

Vue.use(VeeValidate, {
    inject: false,
    delay: 500
});

So, obviously, vee-validate validates the fields 500 ms after they change. This problem might be a race condition between:

  1. The reset() function
  2. The validation function that is triggered with a timeout of 500 ms once the values of the fields change.

I think this could be solved by letting the reset() function also cancel all function that are fired with a timeout or interval?

@mareksuscak thanks for your comment, you are correct but I’m not using timeout to clear the errors, its to emulate a server response time. I just chain another then callback and it seems to work fine.

but you are correct, nextTick should be preferred, since it is there to handle such cases.

Probably because the changes to the model value is being done slower that the errors being cleared, you can append another .then in which you can clear the errors.

here is a small example: https://jsfiddle.net/hcac5je0/1/