Passing "this" inside a promise?

268 views Asked by At

I am trying to learn about promises.

My URL will contain three ID parameters, e.g.

#org=123&num=145&denom=467

and I want to use these to select the values of three select elements on my page (each one with an Ajax source), e.g.

<select id="org"><option selected val="123">Birmingham University</option></select>
<select id="num"><option selected val="145">Maths</option></select>
<select id="denom"><option selected val="467">English</option></select>

The complicated bit is that I need to do an Ajax request for each ID, so that I can pre-fill the name part of the option as well as the ID.

Then once all three requests are complete, I want to continue to render the rest of the page.

I've got most of the way there, but I'm stuck on how to get the value of this inside the getNumerators function. Can anyone help?

setUp: function() { 
   // use hash to set this.globalOptions
   var _this = this;
   _this.setFormValues().then(function() { 
      this.setUpRestOfForm ...
   };
},

setFormValues: function() { 
  return _this.getOrgs()
     .then(_this.getNumerators)
     .then(_this.getDenominators)
     .then(function() {
        return true;
        }
    });
 },

getOrgs: function() { 
    return $.ajax({
        type: 'GET',
        url:'/api/orgs/?q=' + this.globalOptions.orgId,
        dataType: 'json'
    });
},

getNumerators: function(orgIds) { 
   // FAILS: Cannot set property 'orgIds' of undefined
   this.globalOptions.orgIds = orgIds;
   var url = '/api/subjects/?q=' + this.globalOptions.numId; 
    return $.ajax({
        type: 'GET',
        url: url,
        dataType: 'json'
    });
}

Any other advice on the way I'm doing this would also be gratefully received.

1

There are 1 answers

1
Arun P Johny On BEST ANSWER

You can use Funtion.bind()/$.proxy() to pass a custom execution context

setFormValues: function() { 
  return _this.getOrgs()
     .then(_this.getNumerators.bind(_this)) //using bind() - supported in IE9+
     .then($.proxy(_this.getDenominators, _this)) //using $.proxy()
     .then(function() {
        return true;
        }
    });
 }

or you can pass a custom context using context option in ajax

getOrgs: function() { 
    return $.ajax({
        type: 'GET',
        url:'/api/orgs/?q=' + this.globalOptions.orgId,
        dataType: 'json',
        context: this
    });
},