Saras Arya
Saras Arya

Reputation: 3112

How to get data from an API in a Angular Service and store it to be used by anyone in the future

This is more of a writing clean code/ optimizing existing code. I am writing my Angular Services to fetch data from backend like this

angular.module('myApp').service('Auth', ['$http', '$q', 'Config', function($http, $q, Config) {
    this.getUser = function() {
        return $http.get(Config.apiurl + '/auth/user')
            .then(function(response) {
                return response.data;
            }, function(error) {
                return $q.reject(error.data);
            });
    };
}]);

Now in this, I am calling getUser function n number of times from the Database. Now the question is, is it okay to call this service to get n times redundant data or I should it be saved somewhere say rootscope to be accessed later? Or storing in root scope would be bad practice and I should consider some other option or nothing at all? Would like to get some views on Angular Community here.

Upvotes: 0

Views: 1149

Answers (3)

ngCoder
ngCoder

Reputation: 2105

Here is a sample example on how to use factory for sharing data across the application.

Lets create a factory which can be used in entire application across all controllers to store data and access them.

Advantages with factory is you can create objects in it and intialise them any where in the controllers or we can set the defult values by intialising them in the factory itself.

Factory

app.factory('SharedData',['$http','$rootScope',function($http,$rootScope){

    var SharedData = {}; // create factory object...
    SharedData.appName ='My App';
    return SharedData;
}]);

Service

app.service('Auth', ['$http', '$q', 'SharedData', function($http, $q,SharedData) {
   this.getUser = function() {

            return $http.get('user.json')
              .then(function(response) {
                  this.user = response.data;
                  SharedData.userData = this.user; // inject in the service and create a object in factory ob ject to store user data..
                  return response.data;
              }, function(error) {
                  return $q.reject(error.data);
              });

    };

}]);

Controller

var app = angular.module("app", []);
app.controller("testController", ["$scope",'SharedData','Auth',
  function($scope,SharedData,Auth) {

    $scope.user ={};
   // do a service call via service and check the shared data which is factory object ...
   var user = Auth.getUser().then(function(res){
       console.log(SharedData);
       $scope.user = SharedData.userData;// assigning to scope.
   });


  }]);

In HTML

<body ng-app='app'>
    <div class="media-list" ng-controller="testController">

       <pre> {{user | json}}</pre>

    </div>

</body>

Upvotes: 1

W. Basmi
W. Basmi

Reputation: 55

You don't have to, $http already caches your request for you, if the same request is applied in case you set the cache config option to true.

$http.get('/hello', { cache: true})
      .then(onResponse)

or you can either set it for every request, by using either an interceptor or override the http instance in the $httpProvider, to apply the effect for every http request.

app.module('app.module')
    factory('MyHttpInterceptor', function() {
         return {
              request : function(config) {
                  config.cache = true;
                  return config;
              },
              // rest of implementation of the interceptor
         }

    }); 



app.module('app.module')
    .config(['$httpProvider', function($httpProvider) {
           $httpProvider.interceptors.push('MyHttpInterceptor');
           // ... rest of the configuration
      }]);

Or :

app.module('app.module')
    .config(['$httpProvider', function($httpProvider) {
           $httpProvider.defaults.cache = true;
           // ...
     }]);

see : Angular doc for caching

Upvotes: 0

M. Junaid Salaat
M. Junaid Salaat

Reputation: 3783

Instead of rootScope just use a local variable of user in your service that can be accessed from anywhere in your code and so you doesn't have to call the api every time.

angular.module('metaiotAdmin').service('Auth', ['$http', '$q', 'Config', function($http, $q, Config) {
    this.getUser = function() {
        if(this.user){
            return this.user;
        }
        else{
            return $http.get(Config.apiurl + '/auth/user')
              .then(function(response) {
                  this.user = response.data;
                  return response.data;
              }, function(error) {
                  return $q.reject(error.data);
              });
        }
    };
}]);

Hope it helps.

Upvotes: 1

Related Questions