Learn how to use Pusher to enable a rich, real-time user experience with Angular.js, code samples and a demo.
Update: We released an official Angular.js library since that blog post. You can read more about it in this announcement.
Looking for Angular 2? We’ve recently written a new blog post on Pusher and Angular 2 that will help you get started. This blog post focuses on Angular 1.
Front-end application frameworks have given developers the tools to build client side applications with rich user experiences. Let’s say your application is built with one of these frameworks and you want to notify connected clients that something on the server has changed – how can you do that while keeping a rich user experience? This is where Pusher and angular-pusher come into play.
Angular.js is a client side JavaScript framework built by Google. It provides the framework for building either small components that can be plugged into your website or entire single page applications. At the core of Angular.js is a module system that allows creating providers, services, factories, and directives.
All of these are used within controllers to create, retrieve, update, and delete data while providing nice features for manipulating the HTML DOM with little custom JavaScript code. This post won’t focus on the specifics of Angular.js, so some prior knowledge of creating and structuring an Angular.js application is recommended.
In a simple Angular.js application, data is retrieved and sent to and from a backend server through an $http
or $resource
service provided by the framework. Below is an example of retrieving a list of items from an API and updating the selected item using the $http
service.
1var ItemListController = function ($scope, $http) { 2 // initialize a list of items on the scope 3 $scope.items = []; 4 5 var retrieveItems = function () { 6 // get a list of items from the api located at '/api/items' 7 $http.get('/api/items') 8 .success(function (items) { 9 $scope.items = items; 10 }); 11 }; 12 13 $scope.updateItem = function (item) { 14 $http.post('/api/items', item); 15 }; 16 17 // load the items 18 retrieveItems(); 19};
1<div> 2 <table> 3 <tbody> 4 <tr> 5 <th>Name</th> 6 <th>Qty</th> 7 <th></th> 8 </tr> 9 <tr> 10 <td><input type="text" /></td> 11 <td><input type="text" /></td> 12 <td><button type="button">Update</button></td> 13 </tr> 14 </tbody> 15 </table> 16</div>
If we needed to know when items have been updated on the server by another user, we would have to constantly poll the server to find out if the items
array changed.
1var ItemListController = function ($scope, $http, $timeout) { 2 3 $scope.items = []; 4 5 var retrieveItems = function () { 6 // get a list of items from the api located at '/api/items' 7 $http.get('/api/items') 8 .success(function (items) { 9 $scope.items = items; 10 11 // check for item changes 12 $timeout(retrieveItems, 5000); 13 } 14 ); 15 }; 16 17... 18};
As you can see, we just update the items
array every five seconds which isn’t something that we want to keep doing. If a user is making a lot of changes, then we don’t want to keep overwriting the items
array. You could build the logic to only update changed items, but you still have the issue of polling the server every five seconds. It would be much nicer if we could subscribe to an event and wait for a notification of changes in real-time.
Using Pusher will allow us to subscribe to events triggered by other clients. First I’ll show you the simple changes needed in our ItemListController
to use angular-pusher. Then I’ll show you an example of using Pusher in a Node.js server when an item is updated.
First, we need tell our Angular.js application to use angular-pusher. You can do this by either downloading the development or production files from GitHub or using bower install angular-pusher
and loading them into your page with the following script tag:
1<script src="bower_components/angular-pusher/angular-pusher.min.js" type="text/javascript"></script>
This should be loaded after the angular.min.js
file and before your application.js
script.
Now we can tell our application that we want to use the services provided in angular-pusher.min.js
.
1angular.module('myApp', ['doowb.angular-pusher']). 2 3config(['PusherServiceProvider', 4 function(PusherServiceProvider) { 5 PusherServiceProvider 6 .setToken('your_app_key') 7 .setOptions({}); 8 } 9]);
The angular-pusher module has a PusherServiceProvider
that can be configured when creating your application. Here is where you can set your Pusher application key (PusherServiceProvider.setToken('token')
), additional Pusher options (PusherServiceProvider.setOptions(options)
), and a specific version of Pusher (PusherServiceProvider.setPusherUrl(url)
). The Pusher url has a default, but it may be an older version.
Now we can use Pusher in our controller to subscribe to events and be notified when our items
array changes:
1var ItemListController = function($scope, $http, Pusher) { 2 $scope.items = []; 3 4 Pusher.subscribe('items', 'updated', function (item) { 5 // an item was updated. find it in our list and update it. 6 for (var i = 0; i < $scope.items.length; i++) { 7 if ($scope.items[i].id === item.id) { 8 $scope.items[i] = item; 9 break; 10 } 11 } 12 }); 13 14 var retrieveItems = function () { 15 // get a list of items from the api located at '/api/items' 16 console.log('getting items'); 17 $http.get('/api/items') 18 .success(function (items) { 19 $scope.items = items; 20 } 21 ); 22}; 23 24$scope.updateItem = function (item) { 25 console.log('updating item'); 26 $http.post('/api/items', item); 27}; 28 29// load the items 30retrieveItems(); 31}
The following is an example of using Pusher with Express.js running on Node.js. Pusher isn’t restricted to just Node.js applications: there are many server libraries available to make it simple to connect to Pusher. In the Node.js server, we setup our connection to Pusher with a few lines of code and it only takes one more line of code to trigger the actual update notification:
1// setup Pusher 2var Pusher = require('pusher'); 3var pusher = new Pusher({ 4 appId: '12345', 5 key: 'some key', 6 secret: 'my secret... shhh!!!' 7}); 8 9// in our express server 10// setup a post route and trigger the change in Pusher 11app.post('/api/items', function (req, res) { 12 13 // get our item from the req and update the item collection 14 // in a production application this would have validation and items 15 // would be stored in a database. 16 var item = req.body; 17 items[item.id] = item; 18 19 // tell Pusher to trigger an 'updated' event on the 'items' channel 20 // add pass the changed item to the event 21 pusher.trigger('items', 'updated', item); 22 23 // respond with the changed item 24 res.json(item); 25});
All of this code can be found here on GitHub and the gh-pages branch contains the examples that these code snippets came from. The application itself can be found here. Open it now in 2 tabs or windows and witness the power of real-time yourself!
Hopefully this article and the code samples are enough to get your Angular.js application working with Pusher. If you have any questions, our support team is always there to help either via Twitter or via your own support panel.