Angular ‘Controller As’ Communication Utilizing Services

For the past few years the primary means of communication between Angular controllers was to $broadcast events while your controllers listened by using $on handlers. While this certainly works, more and more (and more) Angular experts are moving away from $scope and utilizing Angular’s ‘Controller As’ syntax. With this syntax, we generally do away with injecting scope into our controllers, forcing better design practices, including using services to take over communication between controllers. While this may come off as strange at first if you are used to pub-sub or parent-child techniques, in the end it results in much thinner, more maintainable controllers and reusable services. In this post I am going to describe one technique for establishing controller communication using an Angular service as a mediator.

The Code: Plunker

The Scenario
For this example, imagine you have a layout that lists the last five people added into a system in a table on the right hand side of the screen. This table is handled by one controller, while the form to submit new user data is handled by a separate controller. In this scenario, we need the new user table to automatically update when new users are submitted into the system. So how do we acquire this functionality without using $broadcast or scope inheritance?

Setting Up Your Service
First create a service that exposes a collection of people objects, a method to get all people, and a method to add and remove an individual person. For the sake of simplicity, I am not making HTTP calls to interact with my data but this would be handled in a similar fashion.

The one difference you may notice is the ‘myPeople’ array is stored in and interacted with through the service. This may look awkward to those used to performing these actions in the controller but will prove useful in keeping your Angular controllers as thin and focused as possible. So how does this service help facilitate interaction between controllers?

Controller #1
Controller #1 delegates the ‘addPerson’ functionality to the ‘demoService’.

The involved service will receive this request, take appropriate backend action, and update the array of people.

Controller #2
Controller #2 also takes a dependency on the ‘demoService’, setting the people objects used by your table to those returned from the service. We are also delegating the ‘removePerson’ functionality to our service.

Because the service is shared between controller #1 and #2, the addition of users and subsequent pushing of new data into the ‘myPeople’ array will cause the table repeating over these users to be instantly updated. No further action is necessary.

While this is certainly a simple example, I hope you can see that by delegating the majority of your logic and data interaction to services your Angular controllers can be significantly thinner, easier to manage, and easier to test. While it may seem strange at first to drop $scope and all the toys that come with it, in the long run you will be glad you made the decision. If additional motivation is needed, remember $scope is likely to disappear in Angular 2.0 so it’s time to start preparing!

“Currently, Angular 2.0 has no “scope” object at all. Instead, every view has an execution context that it binds against. There is no prototypal inheritance or any of the strange scope pieces anymore. Essentially, it’s like “controller as” baked in.”
-Rob Eisenburg, Angular 2.0 Team

Until next time, happy coding!

Next ArticleGetting To Know: HTML5 Local Storage