gilgen / ember-pusher

A proper Ember / Pusher integration.
MIT License
100 stars 35 forks source link

Wiring the subscriptions after init. #20

Closed barelyknown closed 9 years ago

barelyknown commented 9 years ago

I'm wiring up subscriptions on a Controller that does not have what it needs during init to define the key for the channel. So, I added a wireSubscriptions function that is called by the Route once it has what it needs during setupController.

app/routes/organization/buyer/loads.js

import Ember from 'ember';

export default Ember.Route.extend(AuthenticatedRouteMixin, {
  model: function() {
    return this.modelFor('organization/buyer').get('loads');
  },

  setupController: function(controller, model) {
    this._super(controller, model);
    var buyer = this.modelFor('organization/buyer');
    controller.PUSHER_SUBSCRIPTIONS['buyers-' + buyer.get('id')] = ['upsert-load']
    controller.wireSubscriptions();
  }
});

app/controllers/organization/buyer/loads.js

import Ember from 'ember';
import { Bindings } from 'ember-pusher/bindings';

export default Ember.ArrayController.extend(Bindings, {
  PUSHER_SUBSCRIPTIONS: {},

  wireSubscriptions: function() {
    var target = this;
    Object.keys(target.PUSHER_SUBSCRIPTIONS).forEach(function (channelName) {
      var events = target.PUSHER_SUBSCRIPTIONS[channelName];
      target.pusher.wire(target, channelName, events);
    });
  },

  actions: {
    upsertLoad: function(data) {
      this.store.pushPayload(data);
    }
  }
});

Two questions:

  1. Should the wireSubscriptions function be extracted from init in the library so that it can be called when necessary?
  2. Is there anything about this situation that feels unusual? Am I missing something?
gilgen commented 9 years ago

I'm confused....why are you doing all this?

If you have dynamic channels/events you just make sure you've defined PUSHER_SUBSCRIPTIONS before calling this._super(). Thats it :)

init: function() {
  var eventName = 'dynamic-event';
  this.PUSHER_SUBSCRIPTIONS = ['foo-channel' : eventName]';
  this._super();
}
barelyknown commented 9 years ago

Because I don't know the eventName until after init.

gilgen commented 9 years ago

Gotcha, so what you use in that case, is just wire.

Just a note, @mmun and I have been talking about moving the pusher functionality into a service so this API will change in the future.

You have access to the pusher service in your routes and controllers because of: https://github.com/jamiebikies/ember-pusher/blob/master/lib/ember-pusher/initializer.js#L29-L30

The API to wire is: wire(target, channelName, events) Where target is the object that will be #send to, channelName is a string, and events is an array of strings.

events: ['foo-event', 'bar-event'],

init: function() {
  this.set('channelName', "example-channel" + this.get('id'));
},

channelNameChanged: function() {
  this.get('pusher').wire(this, this.get('channelName'), this.get('events'));
}.observes('channelName').on('init')
barelyknown commented 9 years ago

OK. That's pretty close to what I did - thanks for clarifying that I wasn't missing something.

gilgen commented 9 years ago

No problem, I've updated the example above a bit! :metal: