Skip to content
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

Forms don't render response unless wrapped into turbo-frame #152

Closed
dmitry-rychkov opened this issue Mar 21, 2021 · 9 comments
Closed

Forms don't render response unless wrapped into turbo-frame #152

dmitry-rychkov opened this issue Mar 21, 2021 · 9 comments

Comments

@dmitry-rychkov
Copy link

dmitry-rychkov commented Mar 21, 2021

As I understand, Turbo must progressively enhance existing classic applications similar to Turbolinks.
I suspect that a lot of people have a code similar to this:

def update
  respond_to do |format|
    if @teacher.update(teacher_params)
      format.html { redirect_to @teacher, notice: t('teacher.flash.updated') }
    else
      format.html { render :edit }
    end
  end
end

There is HTML response and may be another JS or JSON response.

Expected behavior: after form submit I'm redirected or form with errors is rendered
Actual behavior: nothing happens, the form is stuck with locked submit button

It seems the same behavior happens without explicit render call in any POST/PATCH/DELETE action.
It looks like Rails doesn't find turbo_stream format response and responds with empty.

Suggestion: if turbo_stream response is not explicitly defined in controller or view, then use HTML response.

It would make Turbo much more Plug'n'Play. And it will not require developers to update all responses, because now I suddenly discovered that all my update actions across application are just hanging for user, killing the magic of Turbo.

turbo-rails 0.5.9
Rails 6.1.3

P.S. Thank you for the work, I love the idea and realization behind Turbo!

@dmitry-rychkov
Copy link
Author

dmitry-rychkov commented Mar 21, 2021

Update after more tests in different parts of an application, I found that Rails returns empty response if a form is not wrapped around into <turbo-frame>.

Interestingly, I see in logs that it looks like HTML response was actually constructed, but was not returned: Chrome shows empty body response when validation fails.

It is not clear why the form has to be wrapped into turbo-frame, because it saliently and unexpectedly breaks simple plain forms (read local: true).
I struggle to find explanation to such behavior in the code in this repository.
Thanks in advance for pointing out where to look.

@dmitry-rychkov dmitry-rychkov changed the title Forms should use html response when turbo_stream is not defined Forms don't render response unless wrapped into turbo-frame Mar 21, 2021
@pedrofs
Copy link

pedrofs commented Mar 26, 2021

This is the intended behavior of turbo stream requests.

To incrementally adopt turbo-rails on my applications I made all form data: { turbo: false }.

@dmitry-rychkov
Copy link
Author

Hm, but why?
For me it is the same as having to add turbo: false to every link_to in my project. But links don’t do this: they are smart to look for the same frame in response if clicked inside frame, replace whole page otherwise.

Don’t see any drawbacks of having the same logic for forms.

It would make Turbo work more like progressive enhancement, and it would require zero efforts to migrate from Turbolinks. Why not?

@dmitry-rychkov
Copy link
Author

Finally found that #122 is about the same problem.
However, I still don’t understand the reasoning behind such a different treating of plain html forms and links. Forcing so many restrictions on forms doesn’t seem mandatory and can be a pain for upgrade.

Plain HTML must work with or without Turbo. Turbo should not break native web technology.

@jasonfb
Copy link

jasonfb commented Mar 29, 2021

@dmitry-rychkov --- I appreciate what you wrote. good luck with your ideas. In my opinion, these issues make Turbo 1) Not ready for prime-time, and 2) not something to even use on a legacy codebase at all (unless you know what you're doing).

Obviously, you know what you are doing, but after a few weeks of banging my fists on the table frustrated with Turbo-Rails glitches, and seeing the dead-ends that these issues created, it seems very much like an "all-in" technology.

Personally, I would not mix Turbo with heavy javascript (I know the 'light stimulus' approach is recommended), I would not write an app using Turbo unless I had a whole team committed to it, and I would recommend against upgrading and using Turbo if you pre-Rails 6.1 app is doing just fine without it. in other words, while I think it DOES look cool— and there is stuff I like about Turbo— it does not seem like a good time for everybody to stampede towards Turbo right now. Just seems too new. Just my 2¢, your mileage may vary.

@henrik
Copy link

henrik commented Apr 14, 2021

Thanks for this report. Ran into the same thing, I think, and it was a very frustrating first-time experience.

https://turbo.hotwire.dev/handbook/drive#redirecting-after-a-form-submission and https://turbo.hotwire.dev/handbook/drive#streaming-after-a-form-submission give the impression that you can use Turbo in layers – just Turbo Drive for navigation, then add Turbo Frames for more. But the impression I get is that if you want to submit forms, you currently need to use Turbo Frames (or disable Turbo for that form altogether). So either there's a bug or the docs are wrong. (Or I'm mistaken…)

I upgraded from Turbolinks to Turbo and got a bit stumped by the fact that seemingly nothing would happen when I POSTed (e.g. with button_to "Do it", my_action_path, method: :post) and then redirected (even with status: 303). I finally realised after further digging that Turbo seems to treat the response as a "Turbo stream" rather than as plain old Turbo navigation.

It seems the POST request is sent with the request header "Accept: text/vnd.turbo-stream.html, text/html, application/xhtml+xml". And this presumably is what causes the 200 response, after the redirect, to come back with "Content-Type: text/vnd.turbo-stream.html; charset=utf-8". And that presumably causes Turbo to treat it like a stream rather than as navigation.

@mtomov
Copy link

mtomov commented Oct 29, 2021

We've been using Turbo Drive with forms everywhere in our app without a touch of turbo streams. The only "customization" vs regular forms is the addition of the 422 code for unprocessable entity. No other changes are needed.

def update
    if @teacher.update(teacher_params)
      redirect_to @teacher, notice: t('teacher.flash.updated')
    else
      render :edit, status: :unprocessable_entity # add this
    end
end

I wouldn't bother with the respond_to stuff at all. Don't think it's necessary.

Not sure if it's something with Rails UJS that's confusing people, but for us Turbo has been working stellar 💯

@gammafly-co
Copy link

We've been using Turbo Drive with forms everywhere in our app without a touch of turbo streams. The only "customization" vs regular forms is the addition of the 422 code for unprocessable entity. No other changes are needed.

def update
    if @teacher.update(teacher_params)
      redirect_to @teacher, notice: t('teacher.flash.updated')
    else
      render :edit, status: :unprocessable_entity # add this
    end
end

I wouldn't bother with the respond_to stuff at all. Don't think it's necessary.

Not sure if it's something with Rails UJS that's confusing people, but for us Turbo has been working stellar 💯

Wow I got stumped on this tonight; thank you @mtomov. Had no idea the status argument was required. Does anyone know why this is necessary? Is this new w/ Turbo or has this always been required in Rails in order to render the error messages?

@wooly
Copy link

wooly commented Sep 12, 2023

If anyone is discovering this issue via Google, the relevant section of the Turbo handbook is here which explains the 4XX/5XX behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

7 participants