0

I am trying to get the http request result in my first controller. The http request is triggered by another controller. The problem I have is I am not sure how to detect if the request is done in my first controller. I have something like

First controller:

//I am not sure how to get the customer result if
//http requests are trigger by another controllers here.

customerFactory.getCustomerResult????

Second controller:

//trigger the http request..
var id = 1;
$scope.clickme = function() {
    var obj = customerFactory.callApi(id)
}

My factory

customerFactory.callApi = function(id) {
    return getCustomer(id)
        .then(function(customer) {
            return customer;    

         })  
}

var getCustomer = function(id) {
    return $http.get('/api/project1/getCustomer' + id);
}

return customerFactory;

html

<div ng-controller="firstCtrl">
    //codes...
</div>

//other codes..
//other codes..

<div ng-controller="secondCtrl">
    //codes...
</div>

The first and second controller are not related. They are far away from each other. How do I let firstCtrl detect the http request is done and get the customer data? Thanks a lot!

BonJon
  • 779
  • 1
  • 7
  • 21

1 Answers1

1

You can use a factory or a service which is a singleton to both be responsible for making the request and storing the data. The service and factory are both singletons and so the single instance persists for the execution of the application and the data and functions can be referenced from the controllers by injecting the factory or service (both are ways of defining providers with more concise syntax when configuration before use of the service/factory via a provider isn't needed).

angular.module("exampleApp", []).service('ExampleService', ["$http", "$q" ,function ($http, $q) {
    var service = {
        returnedData: [],
        dataLoaded:{},
        getData = function(forceRefresh)
        {
            var deferred = $q.defer();

            if(!service.dataLoaded.genericData || forceRefresh)
            {
                $http.get("php/getSomeData.php").success(function(data){
                    angular.copy(data, service.returnedData)
                    service.dataLoaded.genericData = true;
                    deferred.resolve(service.returnedData);
                });
            }
            else
            {
                deferred.resolve(service.returnedData);
            }

            return deferred.promise;
        },
        addSomeData:function(someDataToAdd)
        {
            $http.post("php/addSomeData.php", someDataToAdd).success(function(data){
                service.getData(true);
            });
        }
    };
    return service;
}]).controller("ExampleCtrl", ["$scope", "ExampleService", function($scope, ExampleService){
  $scope.ExampleService = ExampleService;
}]).controller("ExampleCtrl2", ["$scope", "ExampleService", function($scope, ExampleService){
  ExampleService.getData();
  $scope.ExampleService = ExampleService;
}]);
shaunhusain
  • 19,630
  • 4
  • 38
  • 51
  • Thanks shaunhusain, your example shows one controller makes call which is ExampleService.getData but how it pass the return data to another controller? +1 – BonJon Nov 02 '14 at 02:45
  • Just edited to show a second controller, it's the same as the first though, only real difference between what I'm doing and what you were doing is I'm also storing the data in the service (factory is fine too) so this way it can be referenced from both places. There are some alternatives but typically this is the best way to go that I've encountered. Also to be fair I took my code from this other answer but I've had this question many times and referred people to this other post http://stackoverflow.com/questions/17667455/angular-http-vs-service-vs-ngresource – shaunhusain Nov 02 '14 at 02:48
  • Thanks for your help! My problem is I need to trigger http request in ExampleCtrl but let ExampleCtrl2 get the data. If I understand you correctly, ExampleCtrl2 needs to call getData to get the data too. I only want ExampleCtrl to call getData method. – BonJon Nov 02 '14 at 03:00
  • Nope you can call it from either, ExampleService here is just 1 object that isn't recreated, so the first time it's referenced it gets created after that every other reference to it uses that first object. So you would be okay to inject the service into both controllers and call the method on the service in only one controller but the changes to the data referenced from the second controller through the service will be pointing at the same data object in both controllers here. A major point here is I use angular.copy to populate said data object instead of changing the referenced object. – shaunhusain Nov 02 '14 at 03:03