q.Then
q.Then

Reputation: 2753

How to dynamically set properties of this

I have an AngularJS factory method that is setting properties like this (specifically in the getPageInformation method):

function factoryMethod($http, $q) {
    return function(id) {
        return {
            id: id,

            getPageInformation: function() {
                var deferred = $q.defer();

                $http({
                    method: "post",
                    url: 'getInfo.php',
                    data: {
                        id: this.id
                    },
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
                }).then(function(successResponse) {
                    console.log(successResponse);
                    deferred.resolve('Fetched');

                    for (var attr in successResponse.data) {
                        this[attr] = successResponse.data[attr];
                    }

                }, function(errorResponse) {
                    console.log(errorResponse);
                    deferred.reject('Unable to fetch');
                });

                return deferred.promise;

            }
        }
    }
}

The problem is not with AngularJS, as you can see I am returning and object (from the curly braces syntax), but I need to be able to dynamically set the object properties. I did a loop through the appropriate info I got from the response, but it isn't setting it:

for (var attr in successResponse.data) {
    this[attr] = successResponse.data[attr];
}

Instead, I think the problem is that (when I console.loged this it brought me the entire browser window object), this is failing to refer to the current instance. Is there any I can achieve what I'm doing or is this how it should be working and there is another problem?

Upvotes: 0

Views: 38

Answers (1)

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40296

The meaning of the this variable in Javascript is a pain. You can try searching online for the gory details. For this question I believe it suffices to say that this in callbacks is most probably not what you intuitively expect. You need to create a closure with the real this, commonly done as:

return {
    ...
    getPageInformation: function() {
        var self = this; // The closed variable here
        ...
        $http({...})
            .then(function(successResponse) {
                ...
                for (var attr in successResponse.data) {
                    self[attr] = successResponse.data[attr]; // Use like this
                }
                ...

Upvotes: 1

Related Questions