action-cable-react icon indicating copy to clipboard operation
action-cable-react copied to clipboard

add subscriptions on the fly

Open beornborn opened this issue 9 years ago • 0 comments

Hi, you add listeners on componentDidMount.

    componentDidMount: ->
      cable = @props.cable or @context.cable
      @mounted = true

      for channel in channelNames
        if cable.channel(channel)
          cable.channel(channel).on 'connected', @handleConnected if @handleConnected?
          cable.channel(channel).on 'disconnected', @handleDisconnected if @handleDisconnected?
          cable.channel(channel).on 'rejected', @handleDisconnected if @handleDisconnected?
          cable.channel(channel).on 'received', @handleReceived if @handleReceived?

          for action in cable.channel(channel).actions
            actionMethod = "handle#{_capitalize(action)}"
            cable.channel(channel).on action, @[actionMethod] if @[actionMethod]?

I met necessity to add channels on the fly: I need connect to channels when authorize user

var Layout = React.createClass({
  childContextTypes: {
    snackbarCallback: React.PropTypes.func,
    currentUser: React.PropTypes.object,
    cable: React.PropTypes.object
  },

  getChildContext() {
    return {
      snackbarCallback: this.showSnackbar,
      currentUser: this.state.currentUser,
      cable: this.state.cable
    }
  },

  getInitialState() {
    return {currentUser: {}, cable: new Cable({})}
  },

  componentWillMount() {
    CurrentUser.authenticate((response) => {
      this.setState({currentUser: response.current_user})
      let cable = new Cable({
        UsersOnlineChannel: actionCable.subscriptions.create({channel: 'UsersOnlineChannel'}),
        GamesListChannel: actionCable.subscriptions.create({channel: 'GamesListChannel'})
      })
      this.setState({cable: cable})
    })
  },

key detail is that authenticate is async and I am creating subscription on success.

so I did this hack to make it work

var channelName = 'UsersOnlineChannel'
var UsersOnline = React.createClass({
  mixins: [CableMixin(React), ChannelMixin(channelName)],

  componentDidUpdate(prevProps, prevState, prevContext) {
    if (this.context.cable.channels !== prevContext.cable.chanels) {
      ChannelMixin(channelName).componentDidMount.apply(this)
    }
  },

is there more clean way to setup subcriptioins on the fly?

beornborn avatar May 20 '16 09:05 beornborn