1

I'm creating an hybrid app with Ionic that will load some JSON files that are stored on the device. Since the same data will be used in several different states, I thought it would make sense to store the response to the JSON request and reuse it, rather than re-reading the JSON file over and over.

This question seems to address that scenario, but I can't seem to get it to work. Although the template works when I used a simpler $http.get().success() request, it never fills in since I started trying to use this service.

app.factory('localJsonService', function($http, $q) {
  var localJsonService = {};

  localJsonService.returnLegislators = function() {
    if (this.legislators) {
      return $q.when(this.legislators);
    }
    return $http.get('/data/legislators.json').then(function(response) {
      this.legislators = response.data;
      return this.legislators;
    });
  }

  return localJsonService;
});

//old malfunctioning controller
app.controller('profileController', function($scope, $stateParams, localJsonService) {
  $scope.legislators = localJsonService.returnLegislators();
  $scope.legislator = $scope.legislators[$stateParams.seq_no-1];
  console.log($scope.legislator); //displays undefined
});

//EDIT: newer, working controller (but still loads JSON file on each new state)
app.controller('profileController2', function($scope, $stateParams, localJsonService) {
  localJsonService.getLegislators().then(function(legislators){
    $scope.legislator = legislators[$stateParams.seq_no-1];
  });
});

Is it just a simple change to the service that I'm missing? Or am I going about this the wrong way entirely? I'm running AngularJS v1.3.13, but I'm not opposed to a different version, if that will help.

Thanks for any help you can give me.

Community
  • 1
  • 1
carpiediem
  • 1,918
  • 22
  • 41

2 Answers2

2

Use a promise callback and assign your variables in that callback:

localJsonService.returnLegislators().then(function(legislators){
    $scope.legislators = legislators;
    $scope.legislator = legislators[$stateParams.seq_no-1];
    console.log($scope.legislator); 
});
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • I failed on my answer, but this looks right. The service seems to be returning a singular legislator though, so wont `legislators[$stateParams.seq_no-1]` bomb? – KreepN Jul 02 '15 at 14:40
  • @KreepN yes, there seems to be a mismatch of what is being returned from service. I believe it is a typo and within `$http.get` it should be `legislators` with an `s` – charlietfl Jul 02 '15 at 14:59
  • Thought so, thanks for pointing out my error, I forgot that httpget returns a promise. +1 – KreepN Jul 02 '15 at 15:01
  • That helped (the screen is rendering correctly now), but there does seem to be a problem with my service as well. When I open the browser console to the Network tab, I can see that the JSON file is requested again and again each time the UI state returns to this controller. My goal is to have the file requested by $http only once. – carpiediem Jul 11 '15 at 15:30
  • can use `cache:true` in `$http.get` ... request will only be made once and you won't need your `$q.when` – charlietfl Jul 11 '15 at 15:33
1

If the service data response is not changing, I'd rather user localStorage to cache your response. I'll suggest you ngStorage, that makes it really easy to use localStorage and sessionStorage.

P.S: if datas are changing, then use sessionStorage, that is persistant upon session, but cleaned after app restart.

Example after injecting $localStorage:

Set a default value :

 var jsonDefaultVariable = {};
     jsonDefaultVariable["myDatas"] = false;
 $localStorage.$default(jsonDefaultVariable);

Check for cache :

if($localStorage["myDatas"] !== false){
    factory.myDatas = $localStorage.myDatas;
}else{
   $http(....).success(function(data){
      $localStorage.myDatas = data;
      factory.myDatas = data;
   });
aorfevre
  • 5,034
  • 3
  • 21
  • 51
  • Although I'd like to figure out how to write my own service to handle this, I may wind up using this library in the end. It looks really convenient to use, thanks. – carpiediem Jul 11 '15 at 15:35