Turbo stream append removing objects

Hi everyone, sorry if this was already asked but I was not able to find something related.

I’m using a turbo_stream for an infinite scroll on my page, and it works fine if the records(turbo_frames) appended are order by id. When they are not order by id, they are not really appended but mixed inside the target. Does any one have an ideia?

this is my turbo_strem.erb file:

<%= turbo_stream.append "eventos_#{@event.id}" do %>
  <%= render partial: "guests/guest", collection: @guests unless @guests.empty? %>
<% end %>

if I wrap the render partial in a div the append works fine also.

video: demo

Hola!.Could you explain what do you mean by mixed?. Does turbo remove any element?. Are all elements appending to the DOM or some are removed?.

From what i could see in the code, it seems that maybe there are duplicate records?. Becuase if there is already an item with the same id is present as the id in a turbo frame, it will remove old ones and attach the new one to the DOM. Are you sure every item(frame) has a unique html id attr?

<div id="eventos">
   <--- all your eventos --->
</div>
<%= turbo_stream.append "eventos" do %>
   <--- Untested so i could be horribly wrong --->
  <%= render partial: "guests/guest", collection: @guests unless @guests.empty? %>
<% end %>

…but then you still have to handle pagination…this can be easily handled with lazy loaded turbo-frames and streams, which replace your pagination links with new results and a new set of pagination links - all of which can be lazy loaded…this is a common pattern, perhaps do a google search i’m sure you’ll find tutorials etc.

I’ve created a two-part blog post on implementing a pagination controller with turbo. You can check it out here. Turbo streams with pagination

Hope it helps you out.!

@rockwell @BKSpurgeon Thank you both.

It looks like the GET to the search endpoint is not idempotent, not sure what is happening. I will look further here, where is the issue, but for sure is not Turbo. Sorry, if I waist your time guys.

I saw your posts @rockwell , they are really good. Unfortunately, I only saw them after my implementation was already done.

1 Like

De nada!. Just make sure you return unique elements that have unique HTML id attr. I’m positive that it will most likely solve the issue.

Quick tip, instead of hardcoding ids, you can use the dom_id helper. So, instead of

<%= turbo_stream.append "eventos_#{@event.id}"  %>

You can do

<%= turbo_stream.append dom_id(@event, :events)%>

For example, for an event with id=1, It would generate the id events_event_1.

Disfruta tu tiempo!.