Rails turbo stream only updating one element on the page

65 Views Asked by At

I am trying to use turbo streams to update two pieces on a page (question and answer). I have the following controller

class HomeController < ApplicationController
  def ask
    @question = params[:question]
    @response = Assistant.new.ask(@question)
    
    respond_to do |format|
      format.html { render 'ask' }
      format.turbo_stream
    end
  end
end

where ask.turbo_stream.erb looks as follows:

<%= turbo_stream.update "question", @question %>
<%= turbo_stream.update "response", @response %>

This network tab in the browser shows the following response for /ask

<turbo-stream action="update" target="question"><template>Hey</template></turbo-stream>
<turbo-stream action="update" target="response"><template>Hello! How can I assist you?</template></turbo-stream>

Why does the following snippet render only the @response and not the @question? (Note that I've removed the form code from the snippet below)

<div class="mb-6">
    <h2 class="text-2xl font-semibold">
      <% turbo_frame_tag "question" do %>
        <%= @question %>
      <% end %>
    </h2>
    <p class="text-gray-700">
      <% turbo_frame_tag "response" do %>
        <%= @response %>
      <% end %>
    </p>
  </div>

enter image description here

1

There are 1 best solutions below

2
Alex On BEST ANSWER

You're missing =:

# v
<%= turbo_frame_tag "question" do %>
  <%= @question %>
<% end %>

# v
<%= turbo_frame_tag "response" do %>
  <%= @response %>
<% end %>

params[:question] tells me you probably have an input that's above your turbo frames with the same id, which is being updated instead:

<!--                               vvvvvvvvvvvvv -->
<input type="text" name="question" id="question">

Either change the input name or pick a different id for your turbo frame. Also note, that you don't need turbo frames to use turbo streams:

<div class="mb-6">
  <h2 class="text-2xl font-semibold">
    <div id="question">
      <%= @question %>
    </div>
  </h2>
  <p class="text-gray-700">
    <div id="response">
      <%= @response %>
    </div>
  </p>
</div>