As per the headline, I hereby use the opportunity to thank the LiveView team for finally introducing (as of v0.18.12) the long awaited mechanism for managing the lists - streams.
So far, the only way to do it was with client-side hooks or (far better) Alpine, but still, component-based nested lists kept on having bugs I hope the stream mechanism overcomes completely (as in by design).
Judging by the documentation, it’s gonna be your code that provides the index and if the relative reference is an id, then it means you’ll probably end up maintain an id => index map yourself, but that’s not a big deal in comparison to what was needed before this (the temporary assigns, JS sorting code, etc.)
That’s awesome! Glad to see support for streams in live components. I’ll test this out soon.
But for now onto my next issue with streams It looks like it’s not possible to reset an entire stream.
My use case is a chat app which has the typical layout of a list of conversations on the left and when you click conversation it loads all the messages on the right. Because I couldn’t use streams in a live component I was just using a live view. On mount I would create a stream for the messages and then in handle params I tried to reset the stream with stream(socket, :messages, get_messages[new_conversation_id]) but I get the error existing hook :messages already attached on :after_render.
True, there’s no delete_all and the docs states “Assigns a NEW stream to the socket”.
Now, this is just me thinking aloud, but maybe try removing the assign manually (as in: assign( socket, :name, nil)) and then setting the stream anew OR now that live components support streams, simply reinitialize the entire live component (replace it in its parent template with a new instance of the same component).
Is there any way to keep the stream at a fixed size? I’m thinking about the use case of streaming some logs, where the server doesn’t want to keep the logs in the live view gen server, but you don’t want the client to have the logs keep growing, forever.