Skip to content

angular-actioncable/angular-actioncable

 
 

Repository files navigation

Bower version Build Status License Coverage Status npm downloads

angular-actioncable

An Angular 1.x service for seamlessly integrating Rails 5 (ActionCable) into frontend Angular code. This service opens and maintains a websocket connection between Angular and ActionCable, reconnecting & resubscribing when the connection has been lost, and desynchronising the clients from one another to ease server-side events like code deploys or server restarts.

AngularJS  Ruby

Usage

How to add this to your project

  • Use bower and run bower install angular-actioncable --save (preferred)
  • Use npm and run npm install angular-actioncable --save
  • Download it manually
  • CDN for development https://rawgit.com/angular-actioncable/angular-actioncable/1.3.0/dist/angular-actioncable.js
  • CDN for production https://cdn.rawgit.com/angular-actioncable/angular-actioncable/1.3.0/dist/angular-actioncable.min.js

The One-Liner. (not recommended, but possible)

  <%= action_cable_meta_tag %>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
  <script src="bower_components/angular-websocket/dist/angular-websocket.min.js"></script>
  <script src="bower_components/angular-actioncable/dist/angular-actioncable.js"></script>
  <section ng-controller="SomeController">
    <ul>
      <li ng-repeat="datum in myData">
        {{ datum }}
      </li>
    </ul>
  </section>
  <script>
    angular.module('YOUR_APP', [
      'ngActionCable'
    ])
    .controller('SomeController', function ($scope, ActionCableChannel){
      $scope.myData = [];

      // connect to ActionCable
      (new ActionCableChannel("MyChannel")).subscribe(function(message){ $scope.myData.push(message) });

    });
  </script>

A better way

  <meta name="action-cable-url" content="ws://localhost:3000/cable"/>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
  <script src="bower_components/angular-websocket/dist/angular-websocket.min.js"></script>
  <script src="bower_components/angular-actioncable/dist/angular-actioncable.js"></script>
  <section ng-controller="SomeController">
    <ul>
      <li ng-repeat="datum in myData">
        {{ datum }}
      </li>
    </ul>
    <input ng-model="inputText" /><button ng-click="sendToMyChannel(inputText)">Send</button>
  </section>
  <script>
    angular.module('YOUR_APP', [
      'ngActionCable'
    ])
    .controller('SomeController', function ($scope, ActionCableChannel){
      $scope.inputText = "";
      $scope.myData = [];

      // connect to ActionCable
      var consumer = new ActionCableChannel("MyChannel", {user: 42, chat: 37});
      var callback = function(message){ $scope.myData.push(message); };
      consumer.subscribe(callback).then(function(){
        $scope.sendToMyChannel = function(message){ consumer.send(message, 'send_a_message'); };
        $scope.$on("$destroy", function(){
          consumer.unsubscribe().then(function(){ $scope.sendToMyChannel = undefined; });
        });
      });

    });
  </script>
class MyChannel < ApplicationCable::Channel
  # ...
  def send_a_message(message)
    # ...
  end
end

Support

Supports:

  • Rails 5.0

Examples

API

Factory: ActionCableChannel

constructor function

Methods
name arguments description
new channelName:String
channelParams:Hash:optional
returns instance
Creates and opens an ActionCableChannel instance.
var consumer = new ActionCableChannel('MyChannel', {widget_id: 17});
subscribe callback:Function
returns promise
Subscribes a callback function to the channel.
consumer.subscribe(function(message){ $scope.thing = message });
unsubscribe
returns promise
Unsubscribes the callback function from the channel.
consumer.unsubscribe();
send message:String
action:String:optional
returns promise
Send a message to an action in Rails. The action is the method name in Ruby.
consumer.send('message');
onConfirmSubscription callback:Function Call each time server registers a subscription.
consumer.onConfirmSubscription(function(){ console.log('subscribed'); });

Factory: ActionCableSocketWrangler

singleton

Methods
name arguments description
start Starts ngActionCable services. ActionCableSocketWrangler.start();
This will start by default unless disabled.
stop Stops ngActionCable services. ActionCableSocketWrangler.stop();
preConnectionCallbacks Allows registration of functions which return promises which much be resolved before attempting to establish a connection. ActionCableSocketWrangler.preConnectionCallbacks().push(myFunctionThatReturnsAPromise);
Properties

Exactly one will be true at all times.

name type description
connected Property:Boolean ngActionCable is started and connected live.
ActionCableSocketWrangler.connected;
connecting Property:Boolean ngActionCable is started and trying to establish a connection.
ActionCableSocketWrangler.connecting;
disconnected Property:Boolean ngActionCable is stopped and not connected.
ActionCableSocketWrangler.disconnected;

Configuration: ActionCableConfig

value

Properties

You can override the defaults.

name type description
wsUri String URI to connect ngActionCable to ActionCable. If this is inside a Rails view, it will be read from the action_cable_meta_tag but can still be overridden.
protocols Array Specify protocol headers for the websocket connection. Empty by default.
autoStart Boolean Connect automatically? Default is true.
ActionCableConfig.autoStart= false;
debug Boolean Show verbose logs. Default is false.
ActionCableConfig.debug= true;
my_app.run(function (ActionCableConfig){
  ActionCableConfig.wsUri= "wss://example.com/cable";
  ActionCableConfig.protocols = ['soap', 'wamp'];
  ActionCableConfig.autoStart= false;
});

Frequently Asked Questions

  • Q.: What if the browser doesn't support WebSockets?
  • A.: This module depends on angular-websocket which will not help; it does not have a fallback story for browsers that do not support WebSockets. Please check your browser target support.

Troubleshooting

Object destroy and ActionCable subscriptions

This package is not managing the consumer unsubscribing when you're destroying an Angular object (controller, component, ...) so you must do it.

A simple way to do so is to use the minimal version of the "better way" example:

function SharedMsStockResponse($q, $scope, x2js, stockResponseService, Supplier, ActionCableChannel) {
  var ctrl = this

  var consumer = new ActionCableChannel("MyChannel", {});
  var callback = function(result) {
    console.log("result", result);
    # ctrl is accessible here
  }
  consumer.subscribe(callback).then(function() {
    $scope.$on("$destroy", function() {
      consumer.unsubscribe();
    });
  });
});

angular.module('MY_APP')

.component('sharedMsStockResponse', {
  templateUrl: ...,
  controller: ['$q', '$scope', 'x2js', 'stockResponseService', 'Supplier', 'ActionCableChannel', SharedMsStockResponse],
  bindings: {
    ...
    saleRow: '<'
  }
});

Please have a look at this issue in order to get more information.

Is it any good?

Yes

License

MIT

Development

Setup development

About

Seamless ActionCable integration.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%