Reputation: 319
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
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
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