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.


ANSWERS:


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>

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.


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



 MORE:


 ? Angularjs Controller Injection error
 ? Call another service function from a service function
 ? AnguarJS: using 'this' pointer or return statement
 ? Angular 2 Service error. Cannot find cause
 ? angular, how to stop tracking on service objects
 ? AngularJS - listener in service
 ? Bootstrap at least one component before injecting Router Angularjs 2
 ? Angular - Use scope Variable in Service url
 ? Angularjs How to Load service data after inserting a new record?
 ? Using $uibModal from a factory