Making Angular.js realtime with Websockets

  - - Tutorial

Angular in Realtime

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

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.

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.

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.

Making Angular.js real-time with Pusher

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:

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.

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:

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:

Get Pushing

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.

Pusher is the easiest way to add realtime features to your application.

  • Ron Nitzsche

    Nice article, thanks

    • http://rawkes.com/ Robin Hawkes

      No problem, glad you liked it.

  • gomigomi

    Sounds a little like SignalR.

  • http://www.cnc.io Christian Haintz

    Interesting. What would be the advantages of pusher compared to a socket.io solution?

    • andrewvijay

      You read my mind!!

    • http://rawkes.com/ Robin Hawkes

      I’m Robin, Head of Developer Relations at Pusher. This is a good question, and one we get a lot.

      Primarily, the major advantage is that we handle the WebSocket technology, fallbacks, and the scaling and distribution of your messages for you. This means you don’t need to worry about the many headaches involved in building something from scratch – you can focus on building your app.

      Another advantage is that you can use Pusher on many different platforms, all at the same time, so you’re not just limited to communication between a browser and a server. Some our customers communicate between mobile apps, desktop browsers, physical hardware, and the server all at the same time, with the same API.

      We also offer features out of the box that you’d have to implement yourself in Socket.IO. For example, our authentication and Presence Channels allow you to let others know when someone else joins or leaves a channel.

      These are just a few, I suggest reading through our docs to get a better idea about how we differ: http://pusher.com/docs

      Let me know if you have any more questions!

  • Paul

    What’s the advantage over firebase.com?

    • http://rawkes.com/ Robin Hawkes

      While Firebase aims to store and distribute changes to data, we focus purely on the distribution of your messages without storage on our servers. This allows us to be incredibly flexible and simple to use.

      Did you have anything specific in mind?

      • Paul

        OK so doesn’t work offline. Sounds a bit like AWS’s SNS.

        • http://rawkes.com/ Robin Hawkes

          You wouldn’t be able to have realtime communication offline anyway, whether that’s Pusher, Firebase or someone else. We focus on making sure you can push messages to your users in realtime without having to worry about scalability and setting up complex WebSocket sever infrastructure.

          • Bramagola

            Sure you would. Its called an INTRA net, not INTERnet.

            However, Firebase is locked up tech, just like this, so getting them to give you a server to use inhouse, just like getting a server solution for Pusher, would be another conversation.

        • bmorgan2

          How does firebase.com work offline?

  • Faouzi ELYAGOUBI

    Very Good exemple Thanks !

  • Kamil Biela

    It seems that this code has memory leak. Where is unsubscribe when controller is destroyed?

    • Fabio Biondi

      As Kamil said we need a way to unsubscribe the event and angular-pusher doesn’t include it: https://github.com/doowb/angular-pusher/blob/master/angular-pusher.js

      I’m an AngularJS dev and I will use Pusher in my next project (since my Client already uses it). But I have never used it so I’m trying to understand where I might find problems (I have already worked with Firebase,socketIO and others, so I’m not new to this workflow).

      I’m thinking to update the Pusher factory in angular-pusher.js in order to support the unbind of the channel but before wasting time I would like to ask you :
      1) if you can fix it : )
      2) if you think there might be some complex issues I can’t imagine now

      Thanks in advance

      • Mike

        Filing an issue against the project on github is probably the best way to attract the right people to answer this.

        • Kamil Biela
          • Brian Woodward

            I added an unsubscribe method so it can be used in a controller to … unsubscribe.

          • Fabio Biondi

            wow.. thank you very much for being so fast : )

      • Kamil Biela

        out of curiosity I have checked pusher.js lib, and there is unbind in https://github.com/pusher/pusher-js/blob/master/src/events_dispatcher.js
        I think You could just include this lib pusher.js in head of html and use it directly (or put it in angular.module(‘…’).value(somename, pusherlibvar)). That angular-pusher doesn’t give much except async loading of lib and exposing one method.

  • thijsjacobs

    We’re using Pusher with our Angular.js app on http://piethis.com — and it’s fantastic, faster and more scaleable! Users love the realtime-ness of our app.

    • http://twitter.com/timothykrell Timothy Krell

      I would love to see you post an article on how you use pusher with angular in http://piethis.com. I’m trying to wrap my head around how to do this in our app currently.

  • venkatm

    Can any one suggest me how to develop the small example using angular and pusher.or pls share the sample example