Tag Archives: $http

How to store result from $http into a variable in angularJS

Lately on Stackoverflow.com I came across to several questions regarding the same argument: “How can I cache remote request”, “how to share information between controllers”, “how to avoid several $http calls”. So I decided to create a small project starting from angular seed (https://github.com/angular/angular-seed) to show a possible solution.

The idea is to use a service to store the fetched data and to share it between controllers avoiding several calls during the initial request. For this purpose we need two separate view (view1 and view 2), two separate controllers, a main app.js for the application configuration and a service file to create our caching service (not mentioning common Angularjs files).

App directory structure:

image

App.js is very simple and just bootstrapping the application with the dependencies: ngRoute for the routing the the view’s modules. It defines also the standard view to open in case no route is defined.

   1:  angular.module('myApp', [
   2:          'ngRoute',
   3:          'myApp.view1',
   4:          'myApp.view2'
   5:      ])
   6:   
   7:      .config(['$routeProvider', function ($routeProvider) {
   8:          $routeProvider.otherwise({redirectTo: '/view1'});
   9:      }])

Views are also very simple, basically just injecting the service and prompting the variable value in the html partial.

View1Ctrl:

   1:  angular.module('myApp.view1', ['ngRoute'])
   2:   
   3:      .config(['$routeProvider', function ($routeProvider) {
   4:          $routeProvider.when('/view1', {
   5:              templateUrl: 'view1/view1.html',
   6:              controller: 'View1Ctrl',
   7:              controllerAs: 'vc'
   8:          });
   9:      }])
  10:   
  11:      .controller('View1Ctrl', function (userService) {
  12:          var vm = this;
  13:          userService.getUserInfo().then(function (result) {
  14:              vm.name = result
  15:          }, function (err) {
  16:              vm.name = err
  17:          });
  18:      });

View1.html:

   1:  <p>This is the partial for view 1!</p>
   2:   
   3:  <span>{{vc.name}}</span>

And the core of the project: the userService. The idea is to use service variables to store the fetched result (cachedUser) and to avoid additional call during the request (promise).

Basically after the first call the promise variable is set and avoids any further remote requests, if the cachedUser variable is not set, we will return the promise, otherwise via angular $q defer service we deliver the promise containing the cached value. In every case we are returning a promise avoiding any data type problem in the controller.

   1:  'use strict';
   2:   
   3:  angular
   4:      .module('myApp')
   5:      .factory("userService", userService);
   6:   
   7:  userService.$inject = ["$http", "$q", "$log"];
   8:   
   9:  function userService($http, $q, $log) {
  10:      var deferred = $q.defer();
  11:      var promise = null;
  12:      var cachedUser = null;
  13:      return {
  14:          getUserInfo: function () {
  15:              if (promise) {
  16:                  $log.info("cached value: " + cachedUser);
  17:                  deferred.resolve(cachedUser);
  18:                  return (cachedUser) ? deferred.promise : promise;
  19:              }
  20:              else {
  21:                  $log.info("initial request");
  22:                  promise = $http.get(http://swapi.co/api/people/1/)
                                .then(function (response) {
  23:                      return cachedUser = response.data.name;
  24:                  });
  25:                  return promise;
  26:              }
  27:          }
  28:      }
  29:  }

The project is public accessible over github at the following url: https://github.com/leader80/angular-cache-service, gitclone and try it locally.

Feel free to comment and provide your feedback.

Tagged , , ,