I'm trying to use turbo_frame_tag in my Rails application to manage some tasks. I created a scaffold for my tasks.
I wrapped the page I want to use inside of a turbo frame tag as below:
<%= turbo_frame_tag "modal" do %>
<h1>New task</h1>
<%= render "form", task: @task %>
<br>
<div>
<%# <%= link_to "Back to tasks", tasks_path %> %>
<%= link_to "Cancel", "#", data: {
controller: "modals",
action: "modals#close"
}, class: "cancel-button" %>
</div>
<% end %>
In my home page index.html.erb file I added data to my Add button with the same tag:
<%= link_to "Add", new_task_path, data: { turbo_frame: "modal" }, class: "btn btn-secondary", remote: true %>
The modal is working correctly. It is opened when I click the Add button on my home page. When I try to submit my action to create a new task, I see on my terminal 200 Response and the new task is added to my database.
But (also) I get the "Content Missing" text information on my home page. The page isn't reloaded. In the developer browser I get this error:
turbo.es2017-esm.js:3650 Uncaught (in promise) Error: The response (200) did not contain the expected \<turbo-frame id="modal"\> and will be ignored. To perform a full page visit instead, set turbo-visit-control to reload.
at c.delegateConstructor.throwFrameMissingError (turbo.es2017-esm.js:3650:15)
at c.delegateConstructor.handleFrameMissingFromResponse (turbo.es2017-esm.js:3646:14)
at c.delegateConstructor.loadFrameResponse (turbo.es2017-esm.js:3567:18)
at async c.delegateConstructor.loadResponse (turbo.es2017-esm.js:3441:34)
I have just started learning Ruby on Rails and everything is new for me. I would be grateful for any help and information if anyone had such a problem and how to deal with it.
When you redirect after the form submission, there is no
<turbo-frame>with the same id, so you get frame missing error. For some details and my first attempt at a reusable solution:https://stackoverflow.com/a/75704489/207090
I don't want to post a duplicate answer, but I'll mention that there is a
turbo:frame-missingevent, that you can listen for and handle the error:One caveat with doing a simple
visit(response.url)is that it will be the second request to that url (first one is from the redirect).The ideal place to handle this would be at the redirect response, because that's where you'd know if form submission was successful or not and send redirect as a regular
Turbo.visitoutside of the frame. Which you can do by sending some javascript in a turbo_stream:To make it a bit prettier, do the same thing but in a custom turbo stream action.
Make a custom turbo_stream.redirect action
Tag for "redirect" action would look like this:
Add new action to Turbo to handle it on the front end:
https://turbo.hotwired.dev/handbook/streams#custom-actions
Use generic
actionmethod to render it in a controller or in a template:You can also add
redirectmethod toturbo_streamhelper:Example of how to get out of the frame: