abhinsit abhinsit - 6 months ago 11
Ajax Question

Data object variable in angular service to update via ajax call

Use Case:

I want to create a service in angular which will return me a data object which is a variable inside service, which gets updated once via ajax call.

For first time till data is not received via ajax, it will return {}. Once data is received it will return that data always.

Issue:

The data is properly received in ajax. The structure of data received is an object. I have checked it by logging in console. But next time when this service is called it is again calling ajax as variable inside service is not getting updated.

Can anyone suggest why is this happening and what would be the idle way to achieve above ?

Code:

angular.module('myapp', []).service('TagService', function ($http, CONSTANTS) {
this.tagsData = {};

this.getTagsData = function (cacheMode) {
if (JSON.stringify(this.tagsData) != "{}") {
console.log("returning from cache");
return this.tagsData;
}

$http({
method: 'GET',
url: CONSTANTS['base_url_s'] + 'api/v1/get_all_tags_data/',
params: {'params': JSON.stringify({})}
}).success(
function (data, status, headers, config) {
if (data && data["success"] && data["success"] == true) {
this.tagsData = data["data"];
}
return this.tagsData;

}).error(
function (data, status, headers, config) {
return {};
});

};
});

Answer

You should not use this in your function. The this keyword is function scoped. You're not updating the same variable in your callback and in your first condition.

angular.module('myapp', []).service('TagService', function ($http, CONSTANTS) {
var tagsData = {};

this.getTagsData = function (cacheMode) {
    if (JSON.stringify(tagsData) != "{}") {
        console.log("returning from cache");
        return tagsData;
    }

    $http({
        method: 'GET',
        url: CONSTANTS['base_url_s'] + 'api/v1/get_all_tags_data/',
        params: {'params': JSON.stringify({})}
    }).success(
        function (data, status, headers, config) {
            if (data && data["success"] && data["success"] == true) {
                tagsData = data["data"];
            }
            return tagsData;

        }).error(
        function (data, status, headers, config) {
            return {};
        });

};
});

One more thing, you must use promise rather than returning your datas. Check the documentation about $q here.

The right way should be :

angular.module('myapp', []).service('TagService', function ($http, CONSTANTS, $q) {
var tagsData = {};

this.getTagsData = function (cacheMode) {
    var defer = $q.defer();
    if (JSON.stringify(tagsData) != "{}") {
        console.log("returning from cache");
        defer.resolve(tagsData);
    }else{

    $http({
        method: 'GET',
        url: CONSTANTS['base_url_s'] + 'api/v1/get_all_tags_data/',
        params: {'params': JSON.stringify({})}
    }).success(
        function (data, status, headers, config) {
            if (data && data["success"] && data["success"] == true) {
                tagsData = data["data"];
            }
            return defer.resolve(tagsData);

        }).error(
        function (data, status, headers, config) {
            return defer.reject({});
        });

    };
    }
    return defer.promise;
});

And then you should call:

TagService.getTagsData().then(function(yourTags){
    // yourTags contains your data
});
Comments