user7367398
user7367398

Reputation:

Angular 1 - share data from rest call to another controller

I have two partial pages. In the first page a rest call is made in the ManageUsersTreeViewController. I want this data to get to the second controller ManageUsersTableController. $scope.userData = data; in the getUserData() function is what i need to get to the second controller.

First Controller

app.controller('ManageUsersTreeViewController',['$rootScope', '$scope', '$http', function($rootScope, $scope, $http) {


$scope.getAllUsers = function() {
    $http.get('rest/useraccess/users/').
    success(function (data) {
        $scope.users = data;
    }).
    error(function (error) {
        console.log(error);
    });
};


$scope.getUserData = function(user){
    $http.get('rest/useraccess/' + user ).
    success(function (data) {
        $scope.userData = data;
        console.log("user data returned:" + $scope.userData);

    }).
    error(function (error) {
        console.log(error);

    });
};
}]);

Second Controller

app.controller('ManageUsersTableController',[ '$scope', '$http', '$rootScope', function($rootScope, $scope, $http) {

$scope.maxSize = 3;
$scope.pageNumber = 1;
$scope.pageSize = 20;

$scope.pageSizesForSelect =[5,10,20,50];

}]);

How can i share the $scope.userData in the ManageUsersTreeViewController to the ManageUsersTableController? Any help is much appreciated.

Upvotes: 2

Views: 109

Answers (3)

DudeM
DudeM

Reputation: 23

You cannot use $emit, $broadcast, $on inorder to message data between controllers. the problem with this approch is that the receiving controller may not be loaded yet and there for didnt register it's $on function.

For example if you have 2 page app with seperate controller when the first is loaded it's controller is loaded as well but the seconde page controller isn't there for there will be no controller to catch the first controller $emit or $broadcast.

The above will work only if all involved controllers were allready loaded.

As metion before you can use a service to do the work for you and store the receiving data in the $rootScope. The probllem with this approach is that when your app will grow bigger and will have more and more controller that you will want to communicate between each other , storing all this data in the rootScope is bad approach.

If you wish to use a service, i suggest that you will design a communication system as follow.

  1. Create an array at the size of the number of your conroller in your service.
  2. Each cell in the above array will also be an array , starting with the size of zero.
  3. Inside this service create a const array containing all of your controllers names.
  4. inject ths service into each one of your controllers.
  5. Each Time a controller wants to send data to another controller, it need to iterate the service's names array until it finds the controller name it want to pass data to. one the receiving controller name is found the sending controller know it's index and can push a new message into the receiving controller cell in the array described in 1+2. The "message" can be an object such as : {from:'controller-name', data:{}}.
  6. when a controller start runing it check it's "mailbox" retrive the data and delete the cell if it no longer needed.

Another way you can try out is the creat a Root controller and place it on you body element in your index, such as : ... this controller will run at the moment your app start and can use to store data as i described above

Upvotes: 0

Hyu Kim
Hyu Kim

Reputation: 206

you can use $emit function. this stackoverflow answer explains $emit, $broadcast, $on.

app.controller('ManageUsersTreeViewController',['$rootScope', '$scope', '$http', function($rootScope, $scope, $http) {
  $rootScope.$emit('ManageUserData.Event_or_name_it_yourself', { data: $scope.userData });
}

then, in your other controllers, you can listen to this event. *make sure your view loaded both controllers.

app.controller('ManageUsersTableController',[ '$scope', '$http', '$rootScope', function($rootScope, $scope, $http) {
  // destory the rootscope watcher on scope destory event, as garbage collection. otherwise your rootscope will keep listen on the event
  $scope.$on('$destory', $rootScope.$on('ManageUserData.Event_or_name_it_yourself', function (event, params) {
    $scope.userData = params.data;
    // do what you need to do.
  });
}

Upvotes: 1

Steve Danner
Steve Danner

Reputation: 22158

You're probably going to want to build an angular service to share that data across controllers. Another "down n dirty" option is to attach your userData to the $rootScope (shown below). I think you'll find your app will outgrow that solution quickly, however.

$rootScope.getUserData = function(user){
    $http.get('rest/useraccess/' + user ).
    success(function (data) {
        $rootScope.userData = data;
        console.log("user data returned:" + $rootScope.userData);
        // ...  now just access $rootScope.userData in other controllers
    }).
    error(function (error) {
        console.log(error);
    });

Upvotes: 1

Related Questions