0

Im trying to validate a phone number against a country code in Backbone.js. I need to wait until after the the ajax callback is executed before returning the result of the validation. I'm using Jquerys when method. The model's validate function is:

    validate: function(attrs) {

        this.errors = [];


        if(attrs['phone'].length>0){
            //validate

            console.log('before when ');

            $.when(this.checkPhoneNumber(attrs)).done(function(response){

                console.log('resspone is ');
                console.log(response);

                if(response.valid!==true){
                    that.errors.push({input_tag: 'phone', error: 'Please enter a valid phone number'});
                }

                if(that.errors.length > 0){                  
                   return that.errors;
                }

            });

            console.log('after when ');


        }
        else{

            console.log('in the else so no phone number');

            if(this.errors.length > 0){
               return this.errors;
            }
        }

    },         

And checkPhoneNumber is:

    checkPhoneNumber: function(attrs){

            return $.ajax({
              url: "http://hidden-oasis-1864.herokuapp.com/check-phone-number/"+attrs['country']+"/"+attrs['phone'],
              success: function(response){

                  console.log('in checkPhoneNumber success');

              },
              error: function(){

                    that.errors.push({input_tag: 'phone', error: 'There was an error validating the phone number'});
                    return that.errors;
              }
            });    

    },

In the view, I do:

       if (!this.model.isValid()) {         
           this.processErrors(this.model.validationError);
        }

isValid() runs the model's validate() methos.

But in the logs I always get:

before when  ContactModel.js:46

after when  ContactModel.js:63

MODEL IS VALID ContactItem.js:66

in checkPhoneNumber success 

So when() is not waiting. What am I doing wrong?

user1716672
  • 1,073
  • 2
  • 20
  • 44
  • how are you calling the method that uses the `$.when`? – tkone Mar 25 '14 at 13:24
  • In the view I do: this.model.isValid(), this causes the validate function in the backbone model to be executed. If it returns nothing, its valid, if it returns something, then its invalid.... – user1716672 Mar 25 '14 at 13:31

1 Answers1

2

Try with

checkPhoneNumber: function(attrs){

        return $.ajax({
          url: "http://hidden-oasis-1864.herokuapp.com/check-phone-number/"+attrs['country']+"/"+attrs['phone'],
          success: function(response){

              console.log('in checkPhoneNumber success');

          },
          error: function(){
                console.log("I FOUND MY PROBLEM");

                that.errors.push({input_tag: 'phone', error: 'There was an error validating the phone number'});
                return that.errors;
          }
        });    

},

It looks like the ajax call is returning an error, so done never gets called.

To register a callback for failure, use fail and to register a callback to always execute use then.

David Sulc
  • 25,946
  • 3
  • 52
  • 54
  • `then` takes callbacks for pass/fail/notify, but `always`, er...always executes. – psquared Mar 25 '14 at 13:45
  • But it is going into the success as I see "in checkPhoneNumber success" – user1716672 Mar 25 '14 at 13:46
  • The only way I can get this to worth is by including the option async:false in the ajax request. It works then. But seems pointless to have to use the async:false option with the .when() – user1716672 Mar 25 '14 at 13:58
  • 1
    Good point, but the `done` callback doesn't get executed: you don't "response is" in the console. Try replacing `done` with `always` and see if it works then. Fi it does, take a look at the xhr value returned by `checkPhoneNumber` to determine the problem. – David Sulc Mar 25 '14 at 14:13