SMarello
SMarello

Reputation: 319

AngularJS: How to pass data between controllers during initialization?

In my AngularJS application, I have one controller that manages the user input (input controller) and broadcasts every significant change to the page content controller (actually the content part is managed by several controllers, but let's keep it simple).

The input controller provides a selection between various elements retrieved from a database, on page initalization I have to load the input controller data and provide a default selection to the content controller so it can show significant data on page load.

Now I'm shooting an event on the input controller initialization ($rootScope.$broadcast('inputSelected', inputData);) but clearly angular is not yet initialized so the content controller doesn't catch the event and doesn't render the actual content page.

I made a JSFiddle to demonstrate the behaviour:

On initialization the first controller is shooting an event to the second one with initial data:

myApp.controller('FirstController', function ($scope, $rootScope) {
  $scope.myInput = 'Initial data';

  $scope.broadcast = function() {
    console.log ('broadcasting: ' + $scope.myInput);
    $rootScope.$broadcast('myEvent', $scope.myInput);
  };

  $scope.broadcast();
});

The second controller is listening for 'myEvent':

myApp.controller('SecondController', function ($scope) {
  $scope.$on('myEvent', function (event, args) {
    console.log ('myEvent catched - Data: ' + args);
    $scope.data = args;
  });
});

When the page loads, the first event is not catched by the second controller and the initial data is not passed, then if you press the button BROADCAST (angular is initialised), everything works fine.

So the final question: What's the best approach to pass data between controllers on initialisation? Is there a way to make sure angular is fully initialised before broadcasting the first event?

Upvotes: 4

Views: 876

Answers (2)

Starnuto di topo
Starnuto di topo

Reputation: 3569

Wrapping the $scope.broadcast(); call inside a $scope.$evalAsync works for me:

myApp.controller('FirstController', function ($scope, $rootScope) {
  $scope.myInput = 'Initial data';

  $scope.broadcast = function() {
    console.log ('broadcasting: ' + $scope.myInput);
    $rootScope.$broadcast('myEvent', $scope.myInput);
  };

   $scope.$evalAsync( function() { 
     $scope.broadcast();
   });
});

See: also https://stackoverflow.com/a/23589271/1288109

See the documentation about $evalAsync at: https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$evalAsync

Upvotes: 3

DK3
DK3

Reputation: 403

basically the listeners is not ready and myEvent broadcast already so first you should emit the event to controller "FirstController" and then broadcast to the "SecondController" then it will work.

Here is the fiddle

var myApp = angular.module('myApp',[]);

myApp.controller('FirstController', function ($scope, $rootScope) {
$scope.myInput = 'Initial data';

 $scope.broadcast = function() {
  console.log ('broadcasting: ' + $scope.myInput);
  $rootScope.$broadcast('myEvent', $scope.myInput);
 };
 $rootScope.$on("secondready",function(){
  $scope.broadcast();
 });    

});

myApp.controller('SecondController', function ($scope, $rootScope) {
 $scope.$on('myEvent', function (event, args) {
            console.log ('myEvent catched - Data: ' + args);
     $scope.data = args;
 });
 $scope.$emit("secondready");   
});

https://jsfiddle.net/rbdf6xea/

or you can do by setTimeout as well

Upvotes: 1

Related Questions