Question

I seem to have an issue with the parameters I am trying to set from within the success callback function:

var CampModel = CampDataModel.extend({

    initialize : function(){

        this.fetchActiveAndPending();
        console.log(this.get('active'));
    },

    //Counts active and pending campaigns for front page.
    CountActiveAndPending : function(data){
      var active = 0;
      var pending = 0;

      $.each(data.returnValue,function(index,val){
        if (val.ApprovedOnSite){
          active++;
        }
        else
          pending++;       
      });
      this.set('active',active);
      this.set('pending',pending);
    },

    //fetches  data from server using campModel.
    fetchActiveAndPending : function(){
      console.log('fetching!');
      that = this;
     this.fetch({
        success:function(model,response){
          that.CountActiveAndPending(response);        
        }

      });
       }
    });

    return CampModel;
});

the result of this.get('active') is always the default number. If I try and use this.get('active') from within the success callback function it gives the right result. Is it possible to set a var from within the callback func and call it from outside, let's say the initialize function?

Was it helpful?

Solution

It's not a problem of closures (meaning that your variable isn't accessible from your callback function or something weird like that), it's a problem of execution timing. Your success callback will be executed asynchronously when the client gets the response from the server. The only way to be sure that the response has arrived is to use the listeners (http://backbonejs.org/#Events) or the callbacks (as your success function). If you make sure that a part of your code is executed after the response was received, you'll have the right value for your active parameter.

Here when you do:

console.log(this.get('active'));

The request is still pending, therefore active is still equal to -1. So your problem is still that you're not considering the asynchronous side of your code.

OTHER TIPS

I agree with @Loamhoof, you have a timing issue, one solution is:

initialize : function(){
  this.fetchActiveAndPending(function() {
      console.log(this.get('active'));
  });
},

CountActiveAndPending : function(data){
  ...
},

fetchActiveAndPending : function(completeFn){
  console.log('fetching!');
  var _this = this;
  this.fetch({
    success:function(model,response){
      _this.CountActiveAndPending(response);
      completeFn();
    }

  });
}

p.s. Thanks to @Loamhoof for challenging my previous assumptions and providing an example.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top