kazupon / vue-validator

:white_check_mark: Validator component for Vue.js
MIT License
2.19k stars 431 forks source link

Vue resource in async validation #221

Closed jonas8 closed 8 years ago

jonas8 commented 8 years ago

Hi,

I use vue-resource in an async validation field, but Vue.http or this.$http.post always return a resolved promise, the partials code is following:

The template markup is like this:

 <input id="sms" type="text" 
          detect-change="off" v-validate:sms="{
          required: { rule: true},
          smsVerify: { rule: true, initial: 'off' }
        }" />

Javascript is like this:

export default {
  data () {
    return {
      ...
    }
  },
  validators: {
    smsVerify (val) {
      let promise = this.vm.$http.post(API_CONTEXT.SMS_VALIDATE.resource,..)
      console.log(promise) 
      // the promise here is always resolved, 
      // even if my rest api return http code 403
      ...
    }
  },
  methods: {
    smsVerifyInMethods () {
      let promise = this.$http.post(API_CONTEXT.SMS_VALIDATE.resource,...)
      console.log(promise) 
      // the promise here returns the expectation resolved or rejected
      ...
    }
    ...
  }
}
kazupon commented 8 years ago

You need to implement custom validation that return a promise. http://vuejs.github.io/vue-validator/en/async.html

In the above partials code, You don't return a promise. In real code, You return a promise, don't you?

jonas8 commented 8 years ago

@kazupon Thanks In real code like following, it really works well

  validators: {
    smsVerify (val) {
      return this.vm.$http.post(API_CONTEXT.SMS_VALIDATE.resource,..)
          .then((response) => Promise.resolve(response))
          .catch((error) => Promise.reject(error))
    }
  }

At the beginning, my code is just

  validators: {
    smsVerify (val) {
      return this.vm.$http.post(API_CONTEXT.SMS_VALIDATE.resource,..)
    }
  }

From my understanding,

this.vm.$http.post 

should return a promise with status 'resolved' when response.status >= 200 && response.status < 300, otherwise should be rejected. But It can't work, after some debug, i found this.vm.$http.post(API_CONTEXT.SMS_VALIDATE.resource,...) always return a resolved promise whatever the response.status is. After this i wrote a testing snippet

  methods: {
    smsVerifyInMethods () {
      let promise = this.$http.post(API_CONTEXT.SMS_VALIDATE.resource,...)
      console.log(promise) 
      // the promise here returns the expectation resolved or rejected
    }
  }

In the above code, it printed the expected promise status 'resolved' or 'rejected'. My questions is: Why the `Vue.http return different result between validators and methods.

Thanks again.

kazupon commented 8 years ago

Thank you for your feedback!!

Why the `Vue.http return different result between validators and methods.

Hmm, These difference is context.

However, I think that these difference don't effect to async validation.

I change async example with using vue-resource, and tried to reproduce, but I could confirmed this issues.

Can you reproduce the minimum codes (not real application codes)? If it is possible, I hope that you provide the it with gist.

jonas8 commented 8 years ago

@kazupon Thanks a lot After further reading the code of vue-resource (Promise adapter), things are clear, it's really not a bug of Vue-validator, and sorry for interruption. Details are: this.$http.post doesn't return an ES6 style promise, the thenable chain always return the first promise, not return a new one as ES6 does. i think the purpose is to bind the Vue component context. Such as the following code:

 validators: {
    smsVerify (val) {
      let promise = this.$http.post(API_CONTEXT.SMS_VALIDATE.resource,...)
      // promise.promise is the really ES6 style promise 
      // and with the expected status 'pending'
      ...
    }
  }

And meanwhile, my testing method is unreliable, as above comment said, promise.promise will execute the thenable chain in right way.

kazupon commented 8 years ago

Thank you for your feedback.

I'll try to consider improvement of validator context. Also, I'll try to update async validation section of the documentation.