Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs sharing data between controllers

Tags:

angularjs

I have a service that fetches some client data from my server:

app.factory('clientDataService', function ($http) {
    var clientDataObject = {};
    var cdsService = {
        fetch: function (cid) {
            //$http returns a promise, which has a then function, which also returns a promise
            var promise = $http.get('/clients/stats/' + cid + '/').then(function (response) {
                // The then function here is an opportunity to modify the response
                console.log(response);
                // The return value gets picked up by the then in the controller.
                clientDataObject = {'data': response.data, 'currentClientID': cid};
                return clientDataObject;
            });
            // Return the promise to the controller
            return promise;
        }
    };
    return cdsService;
});

Then in one controller I do:

//get stats
clientDataService.fetch($scope.id).then(function (response) {
    $scope.client_data = {
        'statistics': response.data
    }
});

Which all works very well. However, I'm trying to do a watch from another controller on that service to update it's scope when the data changes, rather then having to re-kick off the http request:

$scope.$watch('clientDataService.clientDataObject', function (cid) {
    alert(cid);
});

I'm just alerting for now, but it never ever triggers. When the page initially loads, it alerts "undefined". I have no errors in the console and all the $injects are fine, but it never seems to recognize that data has changed in the service. Am I doing something wrong in the watch?

Many thanks Ben

like image 462
Ben Kilah Avatar asked Aug 14 '13 08:08

Ben Kilah


People also ask

Is used to share data between controller and view in AngularJS?

14) Which of the following is used to share data between controller and view in AngularJS? Answer: B: "using services" is the correct answer.

What is the $routeProvider in AngularJS used for?

We use $routeProvider to configure the routes. The config() takes a function that takes the $routeProvider as a parameter and the routing configuration goes inside the function. The $routeProvider is a simple API that accepts either when() or otherwise() method. We need to install the ngRoute module.

What is rootScope in AngularJS?

All applications have a $rootScope which is the scope created on the HTML element that contains the ng-app directive. The rootScope is available in the entire application. If a variable has the same name in both the current scope and in the rootScope, the application uses the one in the current scope.

What is $q in AngularJS?

$q is integrated with the $rootScope. Scope Scope model observation mechanism in AngularJS, which means faster propagation of resolution or rejection into your models and avoiding unnecessary browser repaints, which would result in flickering UI.


2 Answers

clientDataService.clientDataObject is not part of your controller's scope, so you can't watch for changes on that object. You need to inject the $rootScope into your service then broadcast the changes to the controllers scopes.

app.factory('clientDataService', function ($rootScope, $http) {
    var clientDataObject = {};
    var cdsService = {
        fetch: function (cid) {
            var promise = $http.get('/clients/stats/' + cid + '/').then(function (response) {
                // The then function here is an opportunity to modify the response
                console.log(response);
                // The return value gets picked up by the then in the controller.
                clientDataObject = {'data': response.data, 'currentClientID': cid};
                $rootScope.$broadcast('UPDATE_CLIENT_DATA', clientDataObject);
                return clientDataObject;
            });
            // Return the promise to the controller
            return promise;
        }
    };
    return cdsService;
});

Then in the controller you can listen for the change using:

$scope.$on('UPDATE_CLIENT_DATA', function ( event, clientDataObject ) { });
like image 153
Brett Henderson Avatar answered Sep 17 '22 15:09

Brett Henderson


Another approach can be:

  1. define new service

    app.factory('DataSharingObject', function(){
       return {};
    }
    
  2. include this new service in controller where we want to store the data

    app.factory('clientDataService', function ($http, DataSharingObject) {
        DataSharingObject.sharedata = ..assign it here
    }
    
  3. include this new service in controller where we want to access the data

    app.factory('clientReceivingService', function ($http, DataSharingObject) {
       ..use it here... = DataSharingObject.sharedata
    }
    
like image 41
deepak pundir Avatar answered Sep 17 '22 15:09

deepak pundir