Coder Social home page Coder Social logo

pusher-angular's Introduction

This library is no longer supported

Pusher Channels AngularJS Library

Build Status Coverage Status

This library is an open source client that allows you to connect to Pusher Channels. It keeps largely the same API as the pusher-js library, with a few differences.

Currently only AngularJS (version 1.x) is supported.

Usage overview

The following topics are covered:

  • Initialisation
  • Subscribing to channels (public, private, encrypted and presence)
  • Accessing Channels
  • Binding to events
    • Globally
    • Per-channel
    • Bind to everything
  • Presence channel members
  • Connection

Initialisation

The first step is to make sure that you have all of the required libraries available to your app before you begin. You'll need something like this in your index.html (or similar):

<!-- AngularJS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.14/angular.min.js"></script>

<!-- pusher-js -->
<script src="//js.pusher.com/4.3/pusher.min.js"></script>

<!-- pusher-angular -->
<script src="//cdn.jsdelivr.net/npm/pusher-angular@latest/lib/pusher-angular.min.js"></script>

<!-- pusher-angular (backup CDN)
<script src="//cdnjs.cloudflare.com/ajax/libs/pusher-angular/1.0.0/pusher-angular.min.js"></script>
-->

If you'd like you can use Bower to install pusher-angular using the following command:

bower install pusher-angular --save

With that in place, to start using the AngularJS library you first need to create a Pusher client in exactly the same way that you create one using the pusher-js library, which is as follows:

var pusher = new Pusher(API_KEY);

There are a number of configuration parameters which can be set for the Pusher client, which can be passed as an object to the constructor, i.e.:

var pusher = new Pusher(API_KEY, {
  authEndpoint: "http://example.com/pusher/auth"
});

This is all documented in full here.

When you've created a Pusher client you then need to pass that client to a $pusher object inside your AngularJS controller, service, etc:

angular.module('myApp').controller('MyController', ['$scope', '$pusher',
  function($scope, $pusher) {
    var client = new Pusher(API_KEY);
    var pusher = $pusher(client);
}]);

You can also see here that you need to inject the $pusher service into any controllers, services, etc where you'd like to use Channels in an AngularJS context.

To make the $pusher service available to be used throughout your app you need to ensure that the pusher-angular module is included in your app. You do this by having the following in your app:

angular.module('myApp', ['pusher-angular'])

Note that you can choose to define just one Pusher client, should you prefer, and then use that as the client throughout your AngularJS app. You can do this by simply instantiating a client as follows:

window.client = new Pusher('API_KEY');

and then instantiating instances of $pusher in your AngularJS app using the standard:

var pusher = $pusher(client);

Make sure that you define client before then referencing it in your AngularJS app though.

This is all of the setup required to have Channels available in your AngularJS app. The content below will explain how you can utilise Channels in an AngularJS app.

Subscribing to channels

Public channels

The default method for subscribing to a channel involves invoking the subscribe method of your $pusher object (named pusher throughout the examples provided here):

var my_channel = pusher.subscribe('my-channel');

This returns a Channel object which events can be bound to.

Private channels

Private channels are created in exactly the same way as normal channels, except that they reside in the 'private-' namespace. This means prefixing the channel name:

var my_private_channel = pusher.subscribe('private-my-channel');

Presence channels

Presence channels are again created in exactly the same way as normal channels, except that they reside in the 'presence-' namespace. This means prefixing the channel name:

var my_presence_channel = pusher.subscribe('presence-my-channel');

It is possible to access channels by name, through the channel function:

channel = pusher.channel('private-my-channel');

It is possible to access all subscribed channels through the allChannels function:

var channels = pusher.allChannels();
console.group('Channels - subscribed to:');
for (var i = 0; i < channels.length; i++) {
    var channel = channels[i];
    console.log(channel.name);
}
console.groupEnd();

Encrypted Channels (BETA)

Like private channels, encrypted channels have their own namespace, 'private-encrypted-'. For more information about encrypted channels, please see the docs.

var my_private_encrypted_channel = pusher.subscribe('private-encrypted-my-channel');

Accessing Channels

It is possible to access channels by name, through the channel function:

var my_private_encrypted_channel = pusher.channel('private-my-channel');

It is possible to access all subscribed channels through the allChannels function:

pusher.allChannels().forEach(channel => console.log(channel.name));

Private, presence and encrypted channels will make a request to your authEndpoint (/pusher/auth) by default, where you will have to authenticate the subscription. You will have to send back the correct auth response and a 200 status code.

Binding to events

Events can be bound to at 2 levels, the global, and per channel. They take a very similar form to the way events are handled in jQuery. Note that this is one area in which the API differs to pusher-js. In pusher-angular, a call to bind will return a decorated version of the callback / handler that you pass as a parameter. You will need to assign this to a variable if you wish to unbind the handler from the object in the future. This is explained in the docs for unbinding below.

Global events

You can attach behaviour to these events regardless of the channel the event is broadcast to. The following is an example of an app that binds to new comments from any channel:

var client = new Pusher(API_KEY);
var pusher = $pusher(client);
pusher.subscribe('my-channel');
pusher.bind('new-comment',
  function(data) {
    // add comment into page
  }
);

Per-channel events

These are bound to a specific channel, and mean that you can reuse event names in different parts of your client application. The following might be an example of a stock tracking app where several channels are opened for different companies:

var client = new Pusher(API_KEY);
var pusher = $pusher(client);
var my_channel = pusher.subscribe('my-channel');
my_channel.bind('new-price',
  function(data) {
    // update with new price
  }
);

Binding to everything

It is possible to bind to all events at either the global or channel level by using the method bind_all. This is used for debugging, but may have other utilities.

Unbind event handlers

Remove previously-bound handlers from an object. Only handlers that match all of the provided arguments (eventName, handler or context) are removed.

var handler = function() { console.log('testing'); };
var decoratedHandler = my_channel.bind('new-comment', handler);

channel.unbind('new-comment', decoratedHandler); // removes just `decoratedHandler` for the `new-comment` event
channel.unbind('new-comment'); // removes all handlers for the `new-comment` event
channel.unbind(null, decoratedHandler); // removes `decoratedHandler` for all events
channel.unbind(null, null, context); // removes all handlers for `context`
channel.unbind(); // removes all handlers on `channel`

The same API applies to unbinding handlers from the client object.

Presence channel members

All presence channels have a members object that contains information about all of the members in the channel. More specific information can be found in the Channels docs.

In this library the members object is setup to automatically reflect changes in members of the channel. That means if you had the following code in a controller:

angular.module('myApp').controller('MyController', ['$scope', '$pusher',
  function($scope, $pusher) {
    var client = new Pusher(API_KEY);
    var pusher = $pusher(client);

    var presence = pusher.subscribe('presence-test');
    $scope.members = presence.members;
}]);

and the following HTML in your view:

<div ng-controller='MyController'>
  {{members.count}}
  {{members.members}}
</div>

your view would update the members count and the members list whenever there was a member added or removed from the channel.

Connection

You can bind to specific events on your $pusher objects connection, such as state_change, using the following code:

var client = new Pusher(API_KEY);
var pusher = $pusher(client);

pusher.connection.bind('state_change', function (states) {
  // var previous = states.previous ...
})

Similarly to the client and channel, you can also bind to all events on a connection using the bind_all method. That looks like this:

var client = new Pusher(API_KEY);
var pusher = $pusher(client);

pusher.connection.bind_all(function (eventName, data) {
  // if (eventName == 'state_change') { ...
})

Contributing

If you'd like to contribute to the library then fork it, hack away at it, improve it, test it, and then make a pull request.

You can make sure that your changes / improvements don't break anything by running the unit tests. To run them just run karma start and then you can go ahead and make changes to the library and the tests and watch the tests run again to see if they're still passing.

You can generate the minimized file as following:

uglifyjs lib/pusher-angular.js -m -o lib/pusher-angular.min.js

Support

If you have questions that aren't answered here or in the code's inline documentation then feel free to create an issue describing your problem.

pusher-angular's People

Contributors

anthwinter avatar bekt avatar bendrucker avatar damdo avatar danieltheodosius avatar hamchapman avatar hugotox avatar lukasdrgon avatar manuelvanrijn avatar marcelcorso avatar mdpye avatar robwalkerco avatar tylercd100 avatar zimbatm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pusher-angular's Issues

Presence Channel Members

Heya,

Thanks for the module!

I have a quick question.. From the docs it states:

var presence = pusher.subscribe('presence-test'); $scope.members = presence.members;

In my controller I've done this, but the count is always zero if I console.log "presence.members.count" - however if I render the variable in a view, it's the correct amount. How do I access the correct value in the controller after calling "presence.members".

Cheers,

Alternative CDN

jsDeliver CDN is down for me now. It is a local problem, it does not work for one network, but I don't have another CDN to fallback.

As an alternative, I suggest cdnjs.com.

What happened to the pusher provider?

The pusher team released a blog post awhile back showing a demo of how to integrate pusher with angular, and it contained this example:

angular.module('myApp', ['doowb.angular-pusher']).

config(['PusherServiceProvider',
  function(PusherServiceProvider) {
    PusherServiceProvider
    .setToken('your_app_key')
    .setOptions({});
  }
]);

What happened to this provider? I don't see access to it anywhere in the current pusher-angular code. I think that being able to configure a provider is extremely important so that pusher can be configured for multiple environments. At the moment, we have to inject the app key and configuration in the service that we have defined to work with pusher, which is not ideal.

I would like for your team to consider re-implementing this provider (if it was indeed ever implemented). Thanks for your consideration. ๐Ÿ˜‹

Binding to client- event throws 'Error: Presence channel required'

Since all the documentation that I've read on Pusher indicates that I should be able to bind to client- events using Private AND Presence channels, and I receive 'Error: Presence channel required' in the browser's console when using a private channel to bind to a client event, I'm assuming that this library expects a presence channel for client- events and does not allow for private channels.

Example not working

After npm install and setting the keys, the example doesn't work.

Also I think this is calling non existing files

  <link href="/css/style.css" rel="stylesheet">
  <script src="/components/angular/angular.min.js"></script>
  <script src="/components/ui-router/release/angular-ui-router.min.js"></script>
  <script src="//js.pusher.com/2.2/pusher.min.js"></script>
  <script src="/components/pusher-angular/lib/pusher-angular.js"></script>

pusher_collaboration

Make $digest application configurable

It would be nice to be able to pass a boolean to configure if $rootScope.$digest() should be run, similar to how the last parameter of Angular's $interval and $timeout services works.

receiving events multiple times

Hi Team,

I am facing a problem with pusher events. pusher sending same message multiple times.

code :
window.pusherClient = new Pusher('xxxxx',
cluster: 'xx'
encrypted: true)

in controller
client = $pusher(pusherClient)
channel = client.subscribe('c-name')

channel.bind "event", (data) ->
vm.message = data.message

Does it work with pusher-js 4.0 ?

Changelog
4.0.0 (2016-12-01)
New major version released due to breaking changes.
[CHANGED] rename bind_all to bind_global
[NEW] unbind_global to remove global bindings
[CHANGED] unbind_all now removes global bindings as well as event specific
[NEW] expose context to pusher level bindings

It looks like bind_all is in use in pusher-angular.

Retry auth request on error

Hi.

I'm using JWT tokens for my app authentication. When the token expires my app automatically sends a refresh token request to the backend and then repeats the original request with the new token.

This isn't happening with pusher-angular. How can I get the response status and retry the request in case it fails the first time?

Thanks in advance!

Broken bind/unbind logic

When binds, the original callback wraps decorator, which is then used to listen to the events.
When unbind, the user passes the original callback, not the decorator, and unbind not happens.

binding to a event on a channel does not pass the context

Hi,
when binding to event on a channel or pusher the context is not set correctly. Within the bind function at the channel and the pusher level the decoratedCallback is used to signal changes to angular however you are not executing the callback with any context. I am using this with the latest pusher version.

bind: function (eventName, callback, context) {
        var decoratedCallback = function (data) {
          callback(data); //This with the latest version of pusher does not use the context set.
                         // callback.call(this,data); looks like it will fix it. the same correction is required at the pusher
          $rootScope.$digest();
        };
        this.client.bind(eventName, decoratedCallback, context);
        return decoratedCallback;
      },

Please could you take a look.

thanks,

Update the library to support Angular 6+

Given that the main pusher client is now written in TypeScript, it would be nice if this library were upgraded to use and work with Angular 6 plus.

Having looked at the current API surface and given Angular now uses observables from RXJS heavily, it is feasible that the API surface could be reduced as subscribe/unsubscribe methods would no longer be needed as this is now taken care of by observables directly.

I am happy to do the work if this is something that would be accepted.

Sean.

Question: Dynamically updating the auth headers

Quick question (maybe its silly, I'm not sure). What is the best way to update the Pusher object auth headers after instantiation?

We have SPA which uses bearer tokens to authenticate access to our API. Atm I've managed to update the Pusher object after the user has logged in, using something like:

pusher.client.config.auth.headers.Authorization = 'Bearer some-sort-of-access-token';

It works, but its pretty hacktastic.

Thanks!
Ben

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.