-
Notifications
You must be signed in to change notification settings - Fork 425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Turbo Stream refresh does not work when responding to a form submission #1173
Comments
@jordinl thank you for opening this issue. Are you rendering the Morphing If the intention is to refresh the page with Morphed content (including the Flash), have you tried replacing the Turbo Stream template rendering with (assuming that you're using Rails) setting a if @widget.save
flash.notice = "Marking 15 payouts ($198.45) as paid."
redirect_to widget_url(@widget)
end |
Hey, found this issue when looking for answers to exactly the same problem (also Turbo 8, turbo_stream.update('venues', partial: 'venues')
turbo_stream.append('turbo-flash', flash_messages) everything works fine, the element is updated correctly. However, when using these as a response to the same action: turbo_stream_refresh_tag # tried also turbo_stream.action(:refresh, '_top')
turbo_stream.append('turbo-flash', flash_messages) Flash is shown, but page is not refreshed even though the response contains: <turbo-stream action="refresh"></turbo-stream>
<turbo-stream action="append" target="turbo-flash"><template>...</template></turbo-stream> The console says:
May that may be an indicator of a faulty local setup?
I know it might be somehow due to a faulty setup on my side, but would like to establish a solution. |
@wawer77 could you change the following bug report template to reproduce your issue? Save this file to `bug_report_template.rb`, then execute with `ruby bug_report_template.rb`require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails"
gem "propshaft"
gem "sqlite3"
gem "turbo-rails"
gem "capybara"
gem "cuprite", "~> 0.9", require: "capybara/cuprite"
end
require "active_record/railtie"
# require "active_storage/engine"
require "action_controller/railtie"
require "action_view/railtie"
# require "action_mailer/railtie"
# require "active_job/railtie"
# require "action_cable/engine"
# require "action_mailbox/engine"
# require "action_text/engine"
require "rails/test_unit/railtie"
class App < Rails::Application
config.load_defaults Rails::VERSION::STRING.to_f
config.root = __dir__
config.hosts << "example.org"
config.eager_load = false
config.session_store :cookie_store, key: "cookie_store_key"
config.secret_key_base = "secret_key_base"
config.consider_all_requests_local = true
config.turbo.draw_routes = false
Rails.logger = config.logger = Logger.new($stdout)
routes.append do
root to: "application#index"
end
end
class ApplicationController < ActionController::Base
include Rails.application.routes.url_helpers
class_attribute :template, default: DATA.read
def index
render inline: template, formats: :html
end
end
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :cuprite, using: :chrome, screen_size: [1400, 1400], options: { js_errors: true }
end
Capybara.configure do |config|
config.server = :webrick
config.default_normalize_ws = true
end
ENV["DATABASE_URL"] = "sqlite3::memory:"
ENV["RAILS_ENV"] ||= "test"
Rails.application.initialize!
require "rails/test_help"
class TurboSystemTest < ApplicationSystemTestCase
test "reproduces bug" do
visit root_path
assert_text "Loaded with Turbo"
end
end
__END__
<!DOCTYPE html>
<html>
<head>
<%= csrf_meta_tags %>
<script type="importmap">
{
"imports": {
"@hotwired/turbo-rails": "<%= asset_path("turbo.js") %>"
}
}
</script>
<script type="module">
import "@hotwired/turbo-rails"
addEventListener("turbo:load", () => document.body.innerHTML = "Loaded with Turbo")
</script>
</head>
<body>Loaded without Turbo</body>
</html> |
I'm seeing the same behaviour als @wawer77 and @jordinl It looks like this is the intended behaviour. The refresh action is generated from the same request which caused the change in the first place. Turbo ignores that action on purpose. See #1019 (comment) |
@seanpdoyle yes. I have:
This is a relatively old app. Up until recently the flash messages were shown as banner right below the navbar. Then I started adding more interactivity with Turbo Streams and it made sense to use a toast (positioned fixed). So we have some endpoints using a banner and others a toast. Which means I can't set the flash and redirect in this situation. |
@daniel-rikowski I'll have to read carefully the entire PR, I'm not entirely sure this is the same issue. So far the way I got it working was to stream the toast update with action cable and then do the redirect: Turbo::StreamsChannel.broadcast_render_to([current_user, :payouts],
target: 'toast-container',
partial: 'shared/update_toast',
locals: { flash: flash_details })
redirect_to merchant_payouts_path(state: @state) This seems worse than allowing to stream an update and a refresh in the same request. |
I was able to get a form submit request to refresh the current page by changing the "request-id" attribute of the turbo-stream tag: In rails I did this: render turbo_stream: turbo_stream.refresh(request_id: nil) This caused the request id to be different from the submitting request ID and tricked turbo into rendering the refresh anyway. In my case, I had a modal dialog that updated a record and I wanted the index page behind the modal to be refreshed with new content once submitted. The modal dialog uses a turbo frame to show the edit page. EDIT: The above code is using the a refresh method on the turbo streams tag builder from turbo-rails like from this PR: hotwired/turbo-rails#595 I'm guessing the user will always want to clear the request-id since otherwise the page will never refresh. |
@caleb Indeed that seems to be the case: But this makes using frames to have an SPA like UI, creating in the same page the list is rendered for example, to not refresh and be forced to use stream actions to attach the new action Someone reading this knows if the idea going forward is to keep using streams for things like this and the auto refresh it's only meant to reflect updates from other people/browsers, or is there a way I'm missing? 🤔 |
@caleb I was curious to see what happened when you send no request id and I was able to reproduce as you say -- what's interesting though is that my turbo frames without morph also seemed to re-load via their src. |
I'm using Turbo 8 so I can trigger refreshes.
In one instance I submit a form (POST request) and I want to show a toast and refresh the page.
The page already has a toast container like this
When I submit the form, I see the server returns:
The toast is correctly shown, but the page is not refreshed.
The text was updated successfully, but these errors were encountered: