hotwired / turbo

The speed of a single-page web application without having to write any JavaScript
https://turbo.hotwired.dev
MIT License
6.69k stars 423 forks source link

Eager-loaded frame fetches but does not render its src #1252

Closed airblade closed 5 months ago

airblade commented 5 months ago

I have an account page which contains content from several different sources so the user can change password, view recent audit logs, etc. To do this I have a frame for each source.

So my /account page has a turbo frame like this:

<turbo-frame id="change_password" src="/password/edit"></turbo-frame>

The /password/edit page looks like this:

<turbo-frame id="change_password">
  <form action="/password" method="post">...</form>
</turbo-frame>

When the submitted form is invalid, the server (Rails) renders /edit/password with a 422 status. Turbo correctly updates the frame to have the form with validation errors. So far, so good.

When the submitted form is valid, the server redirects to /account with a flash message. The incoming /account page sent to the browser is of course the same as the original /account with the addition of the flash message. Turbo replaces the content of the turbo frame containing the submitted form with the incoming frame's content, i.e. nothing. Turbo then GETs the /password/edit page – which is helpful although I don't understand why it re-eager-loads the frame – and receives a 200 response with the /password/edit described above. However this response's content is not inserted into the turbo frame.

The order of requests is:

Load account page:

Submit valid form:

I don't understand why the account page's turbo frame, once it has updated its contents with the incoming turbo frame's contents (which is empty), re-eager-loads its src.

And since it does, I can't figure out why the src's content – the /password/edit's frame's content – isn't inserted into the /account's frame.

Can anyone explain what I'm doing wrong please?

(I realise that even if I figure out how to solve this, the flash message is still discarded. Ideally I'd use morphing but as far as I understand using turbo frames prevents that – unless I can break out of the form server side...but the password-change controller is from a third-party gem which isn't as easy to change.)

airblade commented 5 months ago

Since the end result – the original frame winds up empty – is what I expected, there isn't actually an issue.

Perhaps the fact that the frame re-eager-loads itself after it has been updated is simply an implementation side-effect.