0

I am new to angular js and trying to figure out a way to call the below service in controller. the service is defined as below.

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

  var data = {};

  data.getmyServiceData = function() {
    return $http.get('http://..')
  }

  return data;
}]);

This service is already called at one angular controller. I want to call it in different controller but do not want to make call to the actual service and instead use the data that is received from the previous call. How can i make change to it so that i can call the factory in different controller?

PSL
  • 123,204
  • 21
  • 253
  • 243
user3620975
  • 19
  • 2
  • 6

2 Answers2

0

You can use a promise in your service like this:

app.factory('appFactory',function($http,$q) {
    var data_q = $q.defer();
    var service = {
      getData: getData
    }

    $http.get('http').then(function(response) {
      data_q.resolve(response.data);
    })

    return service;

    function getData() {
      return data_q.promise;
    }
});

And in your controller:

app.controller('AppCtrl',function($scope,appFactory) {
  appFactory.getData().then(function(data) {
    $scope.data = data;
  })
})
Rob
  • 1,840
  • 2
  • 12
  • 19
  • 1
    75% of the code in that service is [redundant](http://stackoverflow.com/questions/23803743/what-is-the-deferred-antipattern-and-how-do-i-avoid-it). It may also be preferable to have the service consumer decide when the request should be initiated rather than initiating it the moment the service is instantiated. – JLRishe Dec 30 '14 at 21:17
  • How is it redundant? The goal is to make only one request to the server and use the data from multiple controllers. – Rob Dec 30 '14 at 21:25
  • Please read the page I linked to, and if you still think it is not redundant, I will be happy to oblige. – JLRishe Dec 30 '14 at 21:30
  • Actually, the suspense is killing me. I'll answer you now. It's redundant because that entire function body can be rewritten in five lines: http://pastebin.com/MmWew1QK – JLRishe Dec 30 '14 at 21:34
  • Right, but you're still hitting the service twice if you need to use that service in another controller. Making two calls to the server. – Rob Dec 30 '14 at 21:36
  • That code I pasted hits the service exactly as much as yours does. And two more lines can be eliminated if you get rid of that `getData` method: http://pastebin.com/0pJk1pNL – JLRishe Dec 30 '14 at 21:38
  • As well as not using the deferred-antipattern, why not just use caching provided by $http? – Martin Dec 30 '14 at 21:40
  • @JLRishe The code I posted only hits the server once. Check out this fiddle and view the console log: http://jsfiddle.net/1ee41na1/ – Rob Dec 30 '14 at 21:43
  • I was referring to you answer regarding returning the http request from the service. Your fiddle is nice alternative to the promise. Learned something new today. Thanks. – Rob Dec 30 '14 at 21:57
0

You just need to include it in your controller's dependencies:

app.controller('MyController', ['$scope', 'myappfactory', 
                                                   function($scope, myappfactory) {
    myappfactory.getmyServiceData().then(function (data) {
        $scope.data = data.data;
    });       
}]);

For a few improvements, you might consider just having your factory return a single function that unwraps the data before returning it:

app.factory('myappFactory', ['$http', function($http) {
  return function() {
      return $http.get('http://..', { cache: true }).then(function (data) {
          return data.data;
      };
  };
}]);

Then you can use it like this:

app.controller('MyController', ['$scope', 'myappfactory', 
                                                   function($scope, myappfactory) {
    myappfactory().then(function (data) {
        $scope.data = data.data;
    });       
}]);
JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • JLRishe - If I try to call the factory from 2-3 controller, will the call be made to service again and again? – user3620975 Dec 30 '14 at 21:39
  • @user3620975 If you use caching, then the call to the service will only be made once. I've modified my answer to use the `cache: true` option. – JLRishe Dec 30 '14 at 21:44