hotwired / turbo

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

`data-turbo-action` doesn't play well with `data-turbo-stream`? #683

Closed ernsheong closed 2 years ago

ernsheong commented 2 years ago

Apologies in advance, this could either be a question or a bug.

Version: 7.2.0-beta.2

I am noticing that if I use data-turbo-stream on a GET link (a new feature), it doesn't do anything with data-turbo-action="advance", ie the URL does not update in the browser. Is this expected behavior or a bug?

If expected, what is the way I should approach if I want a GET link click to change multiple parts of my page? No choice but Stimulus?

marcoroth commented 2 years ago

Hey @ernsheong, thanks for opening this issue!

I'm not sure I'm following 100%. Do you have something like

<a href="/route-that-returns-stream-actions" data-turbo-stream data-turbo-action="advance">Click me</a>

and expect your browser URL to be /route-that-returns-stream-actions after you click on the link?

If so, that's not how the data-turbo-action attribute is intended to be used. You are not actually navigating to the /route-that-returns-stream-actions page, but requesting stream actions from that URL to be applied to the current page your are on. This doesn't involve a page visit.

ernsheong commented 2 years ago

Thank you so much for your response, @marcoroth. Yes it makes sense that this is not how it is intended to be used. I will need to rethink my approach :)

Ultimately either a maintain scroll solution or a data-turbo-permanent solution will be the way to go for me with Turbo Frames.

pySilver commented 1 year ago

@ernsheong I'm a bit late to the show, but this is how I managed to work it out: https://github.com/hotwired/turbo/issues/792

trsteel88 commented 1 year ago

Hey @ernsheong, thanks for opening this issue!

I'm not sure I'm following 100%. Do you have something like

<a href="/route-that-returns-stream-actions" data-turbo-stream data-turbo-action="advance">Click me</a>

and expect your browser URL to be /route-that-returns-stream-actions after you click on the link?

If so, that's not how the data-turbo-action attribute is intended to be used. You are not actually navigating to the /route-that-returns-stream-actions page, but requesting stream actions from that URL to be applied to the current page your are on. This doesn't involve a page visit.

Any chance this behaviour is coming soon? I need to be able to advance a URL while also returning a stream. Not sure why this isn't intended as it is something that would need to be set on a specific link.

BattleBrisket commented 1 year ago

Echoing @trsteel88 sentiments: firing a visit while rendering a stream can be a logical approach.

In my current project, I have nav links that update the central page component (i.e. registering a visit is logical and justified) via stream. The controller action that calls this turbo stream has a full page render for direct navigation. The current thinking is forcing me to choose between the use of streams and good UX navigation.

In contrast, turbo frames can trigger visits while only updating portions of a page. I fail to see a difference between that and implementing similar outcomes via streams.

manuelmeurer commented 1 year ago

Adding myself to the list of people who would gain a lot from this! 😄 I'm building a messenger with a similar setup to @BattleBrisket: a sidebar with a list of existing chats, each one is a link with data-turbo-stram, so I can render streams in the response (one to update the list of chat messages, one to update the frame containing infos about the person you're chatting with). Naturally, I want the URL to advance, so that the URL to a specific chat can be copied.

ratanachai commented 11 months ago

I want the URL to advance for Turbo stream GET request as well. Is there's a plan for this to be added?

maxim commented 7 months ago

Another use case (just happened here): search-as-you-type form that submits via GET. I need to update 3 places: top pagination info, bottom pagination nav, and results themselves. Preferably I do all 3 via turbo_stream. The url should be changing as the query is being entered, with ?q=entered+text. This works if I use turbo frame, but not turbo streams. I might have to switch to a combined frame + streams solution, where I ship stream actions inside the turbo frame.

Edit: I implemented a turbo-frame that ships turbo-stream templates alongside it, and it works. However, now I have an awkward partial that contains the whole <table> (instead of rendering a collection of rows), and I had to use if turbo_frame_request? in controller to avoid sending the entire page (it works either way, but sending the entire page would've been inefficient compared to pure turbo-streams approach).

adampope commented 1 month ago

I've also just been bitten by this. I had a page with a search form frame that targets a results frame. Changing search filters triggered an update to the results with an action=advance. I then needed to also update some stats in a sidebar so swapped from a standard HTML response to a turbo_stream response with two replace actions for the two frames and ran into this problem that the URL stopped updating and navigation back from a search result led to incorrect results being shown. It feels a reasonable use case to support IMO.

The stream action tag inside a single frame response suggested by @maxim seems to work for me, but it feels pretty hacky.