When I run my react-native mobile app, the server says it connects to the PostChannel. It creates the post, however I get no response in the 'received' function so it does not update in real time.
This is my react-native code:
import ActionCable from 'react-native-actioncable';
const APP = {};
APP.cable = ActionCable.createConsumer("http://localhost:3000/cable");
const addSocket = (dispatch) => {
const self = this;
this.subscription = APP.cable.subscriptions.create(
"PostChannel",
{
connected: () => {
console.log("connected: action cable");
},
disconnected: () => {
console.log("disconnected: action cable");
},
received: (data) => {
console.log('received', data); // no response here
dispatch(receivePost(data.post));
}
});
};
Rails code:
Channel
class PostChannel < ApplicationCable::Channel
def subscribed
stream_from "post_channel"
end
end
Model
class Post < ApplicationRecord
validates :user_id, :venue_id, presence: true
after_create_commit { PostBroadcastJob.perform_later self}
belongs_to :user
belongs_to :venue
end
Job
class PostBroadcastJob < ApplicationJob
queue_as :default
def perform(post)
ActionCable.server.broadcast 'post_channel', render_post(post)
end
private
def render_post(post)
ApplicationController.renderer.render post
end
end
post partial
json.id post.id
json.body post.body
json.author post.author.username
json.timestamp time_ago_in_words(post.created_at)
Here is the server log:
Started GET "/cable" for ::1 at 2017-04-19 21:14:36 -0700
Started GET "/cable/" [WebSocket] for ::1 at 2017-04-19 21:14:36 -0700
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
PostChannel is transmitting the subscription confirmation
PostChannel is streaming from post_channel
Started POST "/api/posts" for ::1 at 2017-04-19 21:14:43 -0700
Processing by Api::PostsController#create as JSON
Parameters: {"post"=>{"venue_id"=>4, "user_id"=>1, "body"=>"a"}}
Can't verify CSRF token authenticity.
(0.1ms) BEGIN
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Venue Load (0.4ms) SELECT "venues".* FROM "venues" WHERE "venues"."id" = $1 LIMIT $2 [["id", 4], ["LIMIT", 1]]
SQL (0.5ms) INSERT INTO "posts" ("user_id", "venue_id", "body", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["user_id", 1], ["venue_id", 4], ["body", "a"], ["created_at", 2017-04-20 04:14:43 UTC], ["updated_at", 2017-04-20 04:14:43 UTC]]
(2.0ms) COMMIT
[ActiveJob] Enqueued PostBroadcastJob (Job ID: 4ebbf405-2bd7-43e9-94fc-e4f5195afc0f) to Async(default) with arguments: #<GlobalID:0x007f838d3a5d00 @uri=#<URI::GID gid://backend/Post/50>>
Rendering api/posts/show.json.jbuilder
Post Load (3.8ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = $1 LIMIT $2 [["id", 50], ["LIMIT", 1]]
Rendered api/posts/show.json.jbuilder (0.9ms)
[ActiveJob] [PostBroadcastJob] [4ebbf405-2bd7-43e9-94fc-e4f5195afc0f] Performing PostBroadcastJob from Async(default) with arguments: #<GlobalID:0x007f838d35dfc8 @uri=#<URI::GID gid://backend/Post/50>>
Completed 200 OK in 34ms (Views: 6.3ms | ActiveRecord: 3.1ms)
[ActiveJob] [PostBroadcastJob] [4ebbf405-2bd7-43e9-94fc-e4f5195afc0f] Rendered api/posts/_post.json.jbuilder (16.7ms)
[ActiveJob] [PostBroadcastJob] [4ebbf405-2bd7-43e9-94fc-e4f5195afc0f] Performed PostBroadcastJob from Async(default) in 26.05ms
I tried changing the Job to render the raw post:
def perform(post)
ActionCable.server.broadcast 'post_channel', post
end
And the client receives the data this way. But not in the format I need. So I still need it to use the jbuilder partial. Am I rendering the partial wrong? I've tried a few different ways.
Any suggestions?