I
I
Ismail2020-04-23 11:08:14
Ruby on Rails
Ismail, 2020-04-23 11:08:14

Why is React client not receiving data via ActionCable?

Good afternoon. I'm trying to connect React to ActionCable.
When I send a POST request to the server, I see messages like this:

network cable log

5ea14abd7d161868752400.png

{"type":"welcome"}
{"command":"subscribe","identifier":"{\"channel\":\"BoardsChannel\"}"}
{"identifier":"{\"channel\":\"BoardsChannel\"}","type":"confirm_subscription"}
{"type":"ping","message":1587628697}
{"command":"message","identifier":"{\"channel\":\"BoardsChannel\"}","data":"{\"id\":104,\"title\":\"Sample list\",\"board_id\":30,\"created_at\":\"2020-04-23T07:58:18.738Z\",\"updated_at\":\"2020-04-23T07:58:18.738Z\"}"}


At the same time, if you open the second tab, no data is received, although the client subscribes to the channel.

board channel

class BoardsChannel < ApplicationCable::Channel
  def subscribed
    stream_for "boards_channel"
  end

  def unsubscribed
    stop_all_streams
  end

  def receive(data)
    ActionCable.server.broadcast "boards_channel", data
  end
end



For three models, I have only one channel. What is the problem? Why is the channel not streaming data?
Below is the container that processes the logic and connects the client to the websocket:

BoardsContainer

import React from "react";
import axios from "axios";
import update from "immutability-helper";
import ActionCable from "actioncable";

import { API_ROOT, API_WS_ROOT } from "../../../constants";
import Board from "./components/Board";

export default class BoardContainer extends React.Component {
  constructor() {
    super();

    this.state = {
      lists: [],
    };

    this.createList = this.createList.bind(this);
    this.handleReceiveNewList = this.handleReceiveNewList.bind(this);

    this.goBack = this.goBack.bind(this);
    this.deleteList = this.deleteList.bind(this);
  }

  goBack() {
    window.location.href = "/";
  }

  handleReceiveNewList = (data) => {
    console.log('data:', data);
    this.setState({
      lists: [...this.state.lists, data],
    });
  };

  componentDidMount = () => {
    window.fetch(`${API_ROOT}/lists`).then((data) => {
      data.json().then((res) => {
        this.setState({ lists: res.lists });
      });
    });

    const cable = ActionCable.createConsumer(API_WS_ROOT);

    this.sub = cable.subscriptions.create("BoardsChannel", {
      received: (data) => {
        this.handleReceiveNewList(data);
      },
      connected: () => {
        console.log('connected');
      }
    });
  };

  createList() {
    axios
      .post(`${API_ROOT}/lists`, {
        list: {
          board_id: this.props.board_id,
          title: "Sample list",
        },
      })
      .then((response) => {
        const list = response.data;
        this.sub.send(list);
        const lists = this.state.lists.concat(response.data);
        this.setState({ lists: lists });
      });
  }

  deleteList = (id) => {
    axios
      .delete(`${API_ROOT}/lists/${id}`)
      .then(() => {
        const listIndex = this.state.lists.findIndex((x) => x.id === id);
        const lists = update(this.state.lists, { $splice:  });
        this.setState({ lists: lists });
      })
      .catch((error) => console.error(error));
  };

  render() {
    return (
      <div>
        <Board
          goBack={this.goBack}
          createList={this.createList}
          allLists={this.state.lists}
          board_id={this.props.board_id}
          deleteList={this.deleteList}
          handleReceivedLists={this.handleReceivedLists}
        />
      </div>
    );
  }
}



Create ListController :

def create

def create
      @list = List.new(list_params)

      @board = Board.find(list_params[:board_id])

      if @list.save
        serialized_data = ActiveModelSerializers::Adapter::Json.new(
          ListSerializer.new(@list)
        ).serializable_hash
        ActionCable.server.broadcast "boards_channel", serialized_data
        render json: @list.to_json, status: :ok
      end
    end



What is wrong here and why do clients not receive data, although they are subscribed to the channel?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question