0

We are trying to develop an app using phonegap onsen and angularJS.

I am trying to call a function from a different controllers. I have seen alot of documentation on how to do this like this

But for certain reason it doesn't work for me. Here is my code so far.

module.run(function ($rootScope) {
    $rootScope.$on('some-event-here', function (event, data) {
        console.log('1');
        $rootScope.$emit('show-dialog-of-some-event', data);

        //I also tried
        //$rootScope.$broadcast('show-dialog-of-some-event', data); 
    });
});

module.controller('controller1', ['$scope', '$http',  function($scope, $http) {
    $scope.proceed = function() {
        console.log('0');
        $scope.$emit('some-event-here', {});
    }
}]);

module.controller('controller2', ['$scope', '$http',  function($scope, $http) {
    $scope.$on('show-dialog-of-some-event', function (event, data) {
        console.log('2');
        ons.createDialog('some-dialog.html').then(function(dialog) {                        
            //some code here
        });
    });
}]);

It show on the console '0' and '1' but it doesn't show '2'.

This could be an easy problem but I can't seem to find the problem with my code.

Thanks in advance.

Community
  • 1
  • 1
Eddie
  • 26,593
  • 6
  • 36
  • 58

4 Answers4

1

I think what may be occurring is that you declare an event handler for the event 'show-dialog-of-some-event' in the local scope of controller2, i.e. $scope. You emit an event in the $rootScope. Emitted events bubble up not down, so the event 'show-dialog-of-some-event' does not "bubble down" from the $rootScope to $scope. You may want to define the event handler for 'show-dialog-of-some-event' on the root scope instead, e.g.

    $rootScope.$on('show-dialog-of-some-event', function(e,d) {});
0

If you are communicating between sibling controllers and from parent controller to child controller you have to use $scope.$broadcast but If you want to communication from child to parent you have to use $scope.$emit

Shubham Nigam
  • 3,844
  • 19
  • 32
  • What if you are trying to communicate between parent and child? – Eddie Jun 25 '15 at 05:27
  • but broadcast doesn't work on my end. I tried it and it seems doesn't work on me – Eddie Jun 25 '15 at 05:37
  • I am making fiddle for your problem : till then you can check this link : http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/ very good explanation – Shubham Nigam Jun 25 '15 at 05:38
0

2 things are wrong with your code:

1: $broadcast bubbles events down the scope hierarchy, $emit is for bubbling them up the scope hierarchy, instead use this:

$rootScope.$broadcast('show-dialog-of-some-event', data);

For more info see this answer: $rootScope.$broadcast vs. $scope.$emit

2: the run function of your module will be executed before your controller will attach an event handler for this event, therefore the event will have already passed by the time you configure an event handler in your controller:

Again, see this answer AngularJS app.run() documentation?

So the solution to your answer is:

  • change the $emit to $broadcast
  • move the $broadcast call later into the lifecycle so the controller will have attached its listener

Here's a plunkr where I'm calling $broadcast later in the lifecycle (in this case when the window loads):

http://plnkr.co/edit/W7efiKqIlu4va4AcBTbG

Community
  • 1
  • 1
Robin-Hoodie
  • 4,886
  • 4
  • 30
  • 63
  • I transferred module.run(function ($rootScope) under all the codes but still doesn't work. – Eddie Jun 25 '15 at 05:50
  • @EddieWho Not later in your file, later in the lifecycle, run will be executed before your controller code will be handled regardless of where you put it – Robin-Hoodie Jun 25 '15 at 05:56
  • Forgive my ignorance.. How can you do that? – Eddie Jun 25 '15 at 06:02
  • @EddieWho That's quite alright, I would do it in another controller, perhaps reacting to some kind of event that occurs after your event handler has been attached (if it's logical in your case, maybe reacting to some kind of user input, like clicking a button? ) – Robin-Hoodie Jun 25 '15 at 06:04
  • Sorry.. I dont understand what you mean.. :( – Eddie Jun 25 '15 at 06:15
  • @EddieWho I edited my answer with a plunkr to demonstrate what I meant – Robin-Hoodie Jun 25 '15 at 06:23
0

If you don't need to process anything on rootscope you can just inject $rootScope into controller

module.controller('controller1', ['$scope', '$http', '$rootScope', function($scope, $http, $rootScope) {
    $scope.proceed = function() {
        console.log('0');
        $rootScope.$boardcast('some-event-here', {});
    }
}]);

module.controller('controller2', ['$scope', '$http',  function($scope, $http) {
    $scope.$on('some-event-here', function (event, data) {
        console.log('2');
    });
}]);

It's less clean than using a service but you can use this pattern if it's not too often.

Icycool
  • 7,099
  • 1
  • 25
  • 33