1

I have two controllers in a simple AngularJS app that need to communicate data between one another.

I am trying to use events to perform this communication. I have tried using both $scope.$emit and $scope.$broadcast to trigger the change and $scope.$on to consume the events.

Broadcasting events via either $broadcast or $emit does not seem to result in the resulting $on method being fired

Sample, non-working, of what I am trying to achieve is below.

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

     app.controller('TaskCtrl', function ($scope) {
      $scope.setSelected = function (idSelectedVote) {
          $scope.$broadcast("taskRowSelected");
      };  
    });

    app.controller('WorkRecordCtrl', function ($scope) {
        $scope.$on('taskRowSelected', function (event, data) {
            console.log(data); // 'Data to send'
            console.log("Some Data");
        });

    });

Is there a way to achieve direct communication between two controllers at the same level using events?

If not what would be the best way to facilitate the communication?

4
  • 1
    any reason you can't use a service? Commented Oct 28, 2014 at 6:27
  • @NoahMatisoff how would you use a service in this situation ? I am a relative AngularJs neophyte so not sure if a service is an obvious solution for this situation. Commented Oct 28, 2014 at 9:11
  • Have found this post that describes using a service as suggested. eburley.github.io/2013/01/31/… which seems like it provides the behaviour that I am looking for. From what I can see there is nothing in the style of C# events that neatly provide an eventing mechanism. Commented Oct 29, 2014 at 20:41
  • Only reason I would not use a service for this is to avoid another HTTP request. If it's not an HTTP request find a way to use the service and just inject it wherever. That's the beauty of services. Commented Oct 29, 2014 at 20:49

2 Answers 2

2

I do not think a service would help you in this situation. As I understand it you want controller A to tell controller B when a row has been selected and let controller B handle some data related to that. A service could receive data from controller A and let controller B access the same data, BUT controller B would not know when that data is updated. In controller B you would have to grab the data, put it on the $scope and $watch that data for changes. It is not very elegant and this kind of state change handling is a problem with Angular. Angular is extremely effective at reflecting state update in the UI, but when you want to react to state changes in other ways... like here... it is a problem.

I wrote an article about how you can use FLUX architecture with Angular JS, which helps you handle these kinds of situations: http://christianalfoni.github.io/javascript/2014/09/26/using-flux-with-angular.html.

It might help you out, at least give you some input :-)

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, the post is an interesting starting point. It seems like there is not an obvious solution in AngularJS. I will have to take a look at the flux based solution in more detail. However it does seem to be quite a complex solution to the problem of passing messages between UI elements.
Yep, it can absolutely feel that way :-) The thing though is that FLUX is an architecture that solves multiple things... among those your current issue. So it is a bit to take in to just solve your current challenge, but if you need a good scalable architecture for a project, an architecture that lets you implement new controllers without worrying about how existing controllers are connected, it is a very good way to go. At least in my experience :-)
0

To achieve that you can use $rootScope, but I think it isn't the best practice, that's why I would prefer to use Service. But if you want exactly events, then use $rootSCope

2 Comments

Narek how would you use a service in this case. As I noted above, I am a AngularJS neophyte so not sure if this is an obvious solution.
that's why Ive wrote if it can meet your needs then use $rootScope or more better solution create 3rd controller and put your 2 controllers within it

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.