ruby-on-railsturbo

Rails turbo stream only updating one element on the page


👋🏽 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


Solution

  • 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>