2

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.

3 Answers3

1

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);
    });
Steve Danner
  • 21,818
  • 7
  • 41
  • 51
1

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.
  });
}
Hyu Kim
  • 206
  • 2
  • 11
  • This send the data but produces Error: [$controller:ctrlfmt] Badly formed controller string ''. Must match `__name__ as __id__` or `__name__`. in the browser error. My name looks fine as i set a console.log("h") and it prints it. It only happens when i emit –  Jan 31 '18 at 18:05
  • it doesn't seem to be created by my answer. check this thread maybe? https://stackoverflow.com/questions/39633425/controllerctrlfmt-badly-formed-controller-string-must-match-name-as – Hyu Kim Jan 31 '18 at 18:17
  • So i found the problem i had a closing but no opening one. That fixed the error. –  Jan 31 '18 at 19:23
0

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

DudeM
  • 23
  • 4
  • please see the above accepted answer that worked for me.Using emit/boradcast and $on. –  Feb 03 '18 at 19:38
  • How did you manage to broadcast to the second controller before it was loaded ? – DudeM Feb 04 '18 at 06:16
  • I think in my case, I have a page where i am rendering two partial pages into it. So, in this perspective. controller 1 is first page and controller 2 is the second partial page. They are loaded at the same time. –  Feb 04 '18 at 21:18
  • if this is the case so you'r right the accepted answer is better , but will not hold for cases i have mentioned – DudeM Feb 05 '18 at 06:12
  • I felt like I owe you an explanation. generally, using service approach is better fit since that covers more cases, and it is something you will need to know how to implement if you decide to continue to work with Angularjs. I also mentioned to make sure your view loads both controllers which @DudeM is right about - your case worked because $http network call is slower than angular's event listener controller loading speed. if you have emitted event without network call, it works sometimes not works sometimes. I answered it with $emit so you could solve it and move on quickly. cheers – Hyu Kim Feb 06 '18 at 15:51