question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Duplicate content, Turbo stream added an already existing item

See original GitHub issue

I am currently working on an app that heavily leans on Hotwire (with Rails), I love working with it! Our apps feels so much more responsive because of Hotwire. 🚀

There is one thing that I’m struggling with right now. Our app uses a lot of background jobs and sometimes the jobs are delayed for a couple of seconds.

This is our problem: Our app has a form where users create Vehicles. When the vehicle is created, I redirect the user back to the Vehicle#index. What sometimes happens, is that after the page is rendered by the server, the Turbo Stream job is picked up. Which sends the created vehicle to the user, even if the page already has that content. If that happens the user sees two identical vehicles (with the same dom_id’s), one rendered by the page render, and one added from the Turbo Stream.

It would help if Turbo would check if an id already existed, before blinding appending it to the target. Is that something you would be open to? If so, I would love to contribute to this project.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:5
  • Comments:16 (13 by maintainers)

github_iconTop GitHub Comments

3reactions
dhhcommented, Apr 12, 2021

I think the jumping around is a feature not a bug. This would allow you to reorder things. If you need full control over the order of a list, you’ll need to render the entire container instead. But as a basic default, I’d like to see option C. We remove any duplicates, then do as we’re instructing.

In addition to that, we could introduce two new directives: update-or-append and update-or-prepend. Those would essentially do option B, but give you the control of whether to append or prepend on those that don’t match an existing ID.

1reaction
tleishcommented, Apr 7, 2021

Don’t append or prepend children with the same ID as existing ones

This doesn’t seem like a good idea to me, as the content of the ID might have changed and the updated content would not be added.

Remove target children with conflicting ID before adding template

This may cause page content to jump around. A developer might want to append or prepend an updated item at the beginning or end of a list, however considering this is mostly a race condition, I can’t imagine the content to be that stale and not already at the beginning or ending of a list.

Replace children with conflicting ID instead of append/prepend

I prefer this option over the other options.

I believe a cleaner version to my original code might be something like:

append() {
  this.replaceDuplicateChildren()
  this.targetElement?.append(this.templateContent)
}

replaceDuplicateChildren() {
  this.duplicateChildren.forEach((elementChild, templateChild) => {
    elementChild.replaceWith(templateChild);
    templateChild.remove();
  })
}

get duplicateChildren() {
  return [...this.templateContent.children].map(templateChild => (
    [this.targetElement?.getElementById(templateChild.id), templateChild]
  )).filter((elementChild, templateChild) => elementChild);
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Turbo stream actions - Turbo Reference
A reference of everything you can do with Turbo Streams.
Read more >
Rails turbo stream - Stack Overflow
Turbo prepend and append actions take the id of direct child nodes into account and replace them instead. If you want to get...
Read more >
Conditional Rendering With Turbo Stream Broadcasts - Colby.so
Combining Turbo Streams and Frames to conditionally render content based on session variables like current_user.
Read more >
Realtime partial page updates with Turbo Streams - YouTube
In this episode, you'll see how to setup and install turbo -rails to create partial page updates with Turbo streams in your Ruby...
Read more >
Another CRUD controller with Turbo Rails - Hotrails
We can create some dates and add line items to those dates. ... by making the CRUD on dates without using Turbo Frames...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found