ken
ken

Reputation: 9013

getting 'this' with named thenable

I'm stumbling around with promises in Ember and have a problem where I can get code to work within an anonymous function but prefer the clarity a named function would provide but in doing so I loose my reference to this.

So, for example I have a Ember Data model called 'enumeration' and so I've created a helper class where I can specify the enumName property and when the promise is evaluated the enumList get populated with the results of the appropriate enumeration record:

module.exports = App.Enumeration = Ember.Object.extend({

    // reference to the ember-data store
    store: null,
    // this is the 'id' of in the enum model
    enumName: null,         
    // the enum is converted to a promise and either looked up using the Enum model or passed through as an array
    enumPromise: null,
    enumChanged: function() { 
        var _this = this;
        this.set('enumPromise', this.get('store').find('enum', enumeration)
            .then(function(success) {
                _this.set('enumList', success.get('data'));
            })
        );
    }.observes('enumName'), 

    enumList: []
});

This seems to work as expected, however I'd like to have the then(success,fail) call be sent to named functions:

module.exports = App.Enumeration = Ember.Object.extend({

    // reference to the ember-data store
    store: null,
    // this is the 'id' of in the enum model
    enumName: null,         
    // the enum is converted to a promise and either looked up using the Enum model or passed through as an array
    enumPromise: null,
    enumChanged: function() { 
        var enumeration = this.get('enumName');
        var _this = this;
        this.set('enumPromise', this.get('store').find('enum', enumeration)
            .then(this.successfulEnumRetrieval,this.failedEnumRetrieval);
        );
    }.observes('enumName'), 

    enumList: [],

    successfulEnumRetrieval: function(result) {
        this.set('enumList', result);
    },
    failedEnumRetrieval: function(error) {
        console.log('failed retrieving enumeration: ', error)
    }
});

The problem I'm having is how to gain access to the App.Enumeration's context (aka, "this"). In the named functions, somehow they fail complaining that set() isn't part of the object. I suspect this is a broader Javascript scoping problem but whether it's a "promise" problem or a "javascript scoping" problem I could use some help.

Upvotes: 0

Views: 79

Answers (1)

maheshsenni
maheshsenni

Reputation: 782

You were right when you said that this is a broader Javascript scoping problem. Well, not a problem as such. The right way to do this would be using Function.prototype.bind(). Here is a nice article about it.

You can use it like this in your code.

this.set('enumPromise', this.get('store').find('enum', enumeration)
    .then(function(success) {
        this.set('enumList', success.get('data'));
    }.bind(this))
);

Upvotes: 1

Related Questions