0

I am trying to use $http.get() response as a service providing to controllers. Please help!

erp.service('elementData',['$http', '$cacheFactory', function($http, $cacheFactory){
    var fetchCache = $cacheFactory('ele', {number: 1}); 

    $http({url: "./php/fetchElement.php", 
    method: 'GET'}).success(function(data){
        fetchCache.put(1, data.records);
        console.log(fetchCache.info('ele'));        
        //return fetchCache.get(1);
    });
    console.log(fetchCache.info('ele'));



}])

console.log(fetchCache.info('ele')); provide different result.

1
  • .success and .error are depricated. Use .then and .catch also as part of the options object .get('/url/here', opts) you can provide a cache value. Set to true and it will deal with the cache, or provide it with a cacheFactory object. It will do all the work for you. here Commented Mar 24, 2016 at 9:29

3 Answers 3

1

To effectively cache the response from an HTTP call, and return that if present, I'd do something like this

angular.module('app').factory('dataService', dataService);
dataService.$inject = ['$http', '$q'];

function dataService($http, $q) {
    var service = {
        getGroups: getGroups,
        _groupCache: null
    };

    return service;

    function getGroups() {
        // Return from local cache variable if we have it.
        if (service._groupCache) return $q.resolve(service._groupCache);
        // Otherwise, return from API.
        return $http.get("api/ms/groups/").then(
            function (response) {
                service._groupCache = response.data;
                return response.data;
            }
        );
    }

This can then be injected into your controller and used like follows:

angular.module('app').controller('PageCtrl', PageCtrl);

PageCtrl.$inject = ['dataService'];

function PageCtrl(dataService) {
    var vm = this;
    // "Public" properties
    vm.groups = null;
    dataService.getGroups().then(function (groups) {
        vm.groups = groups;
    });
}

You should then have access to groups inside your page. The first time this code runs, _groupCache on the service will be null, so it will send the HTTP request. On subsequent runs, _groupCache will be populated. You could further refine this by storing the cached groups in local storage on the browser, which would keep it cached even after page loads.

Note that the return of the getGroups function will ALWAYS be asynchronous, so anything that needs that data should be chained onto a .then on the return of getGroups as in this example.

In your example, the .success callback will be executed asynchronously, therefore the second console.log will execute before the first. To fix just that problem, you'd re-write as this:

erp.service('elementData',['$http', '$cacheFactory', function($http, $cacheFactory){
    var fetchCache = $cacheFactory('ele', {number: 1}); 

    $http({url: "./php/fetchElement.php", 
    method: 'GET'}).then(function(data){
        fetchCache.put(1, data.records);
        console.log(fetchCache.info('ele'));        
    }).then(function () {
        console.log(fetchCache.info('ele'));
    });
}])
Sign up to request clarification or add additional context in comments.

2 Comments

@user2671755 Regarding your question in a comment to another answer, there is no problem with caching the result as you have, but you'd need to check the cache before calling $http get.
@user2671755 I've updated my answer to show how you can cache data in a local variable within a factory/service.
0

you can use a service variable.

erp.service('elementData',['$http', '$cacheFactory', function($http, $cacheFactory){
    var resource = {};
    // var fetchCache = $cacheFactory('ele', {number: 1}); 
    resource.loadedData = null;
    resource.getData = function(callback){  
      $http({url: "./php/fetchElement.php", 
      method: 'GET'}).succes(function(data){
        callback(data);
      });        
          //return fetchCache.get(1);
    }
    console.log(fetchCache.info('ele'));

}]);


/*....
In side of your controller */ 
  if(elementData.loadedData){
    $scope.elementData = elementData.loadedData;
    process();
  } else {
    elementData.getData(function(data){
      $scope.elementData = data;
      elementData.loadedData = data;
      /*
        if you want set it on localStorage you can use as
        localStorage.loadedData instead of elementData.loadedData;
      */
      process();
    });
  }
  function process(){
    /* then you can use your data*/
  }
//....

3 Comments

Where you have /* then you can use your data */ is misleading, because at that point, the asynchronous callback to getData will still not have returned - the async problem is just moved to a different place in the code.
Is there any way to cache the fetched data and reuse. Is that right when I state that with above solution, it fetches the server every time we use data and effects performance ( speed)?
@MarkHughes you are right, I'll edit it as you say and user2671755 you can set it on localstorage if you want fetche it once.
0

Thanks for all your help. I also found this:

erp.run(['$http', '$rootScope',
    function($http, $rootScope) {      
     $http({ cache: true, url: './php/fetchElement.php', method: 'GET'})
        .success(function(data) {
          $rootScope.resource = data.records;         
        });
    }
]);

erp.service('elementData',['$rootScope',
   function($rootScope) {
        //console.log($rootScope.resource);
        if($rootScope.resource){
            return $rootScope.resource;
        }
    }
]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.