satish
satish

Reputation: 953

How do I pass a paramter via Javascript to my ActionCable subscription?

I'm using ACtionCable to create web sockets. This is with Ruby on Rails 5.1. How do I pass a parameter to my channel? I would like to have different channels, based on a "worker_id" param. I tried passing the parameter in my Javascript when I crated my ActionCable web socket ...

    App.work = App.cable.subscriptions.create(
      'WorkChannel',
      {
        worker_id: document.getElementById('worker_id').value,
        connected: function(data) {
          var data = document.getElementById('curWork').value;
          // If tehre is a job already there, start working on it
          console.log("connected to web socket! Looking at data:" + data);
          if (data != "") {
            console.log("sending data : " + data);
          }
        },
        received: function(data) {
          console.log("received data from channel:" + data);
          _onMessage( data );
        }
      });

Here is my app/channels/work_channel.rb file,

class WorkChannel < ApplicationCable::Channel

  # Data is received as a hash when sent by the client as JSON
  def receive(data)
    worker_id = params[:worker_id]
    puts "receive worker id: #{worker_id}"
    websocket = Rails.cache.fetch("websocket_workers")[worker_id]
    puts "received data: #{data} class: #{data.class}"
    puts "open? #{websocket.open?}"
    if !websocket.open?
      puts "not open reconnecting."
      websocket.connect
      puts "open now? #{websocket.open?}"
    end
    websocket.send( data.to_json )
  end

  def subscribed
    channel_name = "work#{params[:worker_id]}"
    puts "channel name: #{channel_name}"
    stream_from channel_name
  end

end

but the

channel_name = "work#{params[:worker_id]}"

line is always evaluating to just "work" and it doesn't seem like the parameter is getting passed at all, even though I have verified in my JS that the value is defined. What's the right way to create the consumer subscription while allowing passage of a parameter?

Upvotes: 1

Views: 2423

Answers (1)

Laith Azer
Laith Azer

Reputation: 619

The first argument of create should contain the channel and worker_id as follows:

App.work = App.cable.subscriptions.create(
  {
    channel: 'WorkChannel',
    worker_id: document.getElementById('worker_id').value,
  },
  {
    connected: function(data) {
      var data = document.getElementById('curWork').value;
      // If tehre is a job already there, start working on it
      console.log("connected to web socket! Looking at data:" + data);
      if (data != "") {
        console.log("sending data : " + data);
      }
    },
    received: function(data) {
      console.log("received data from channel:" + data);
      _onMessage( data );
    }
  });

Upvotes: 1

Related Questions