Skip to content

Race-condition between page refresh and lazy-loaded Turbo Frames #1415

@andyundso

Description

@andyundso

very simplified, my page looks like this:

Image

The Turbo Frame is configured to be lazy-loaded, as well as to use morph to replace the content. I use page refreshes to refresh the content of the entire page.

In this sub-content, I have a details element and I tried to prevent that it closes when morphing is applied. So I first hooked into turbo:before-morph-attribute to check if the open attribute is modified and cancelled out this event.

preventAttributeToggle(event) {
  const {attributeName} = event.detail;

  if (attributeName === "open") {
    event.preventDefault()
  }
}

However, sometimes the detail element still closed. I saw that events of the type turbo:before-morph-element arrive on the details element as well, where newElement is undefined. My guess is that while my lazy-loaded Turbo Frame refreshes, the morphing operation of the entire page is still ongoing. since the details element is part of the lazy-loaded Turbo Frame, it will not be included in the page refresh response of my server, therefore idiomorph finds no new element to match with it and would it in theory remove it. So I tried to cancel out this event as well, because I do not want my element to be removed:

preventOnMorphToggle(event) {
  if (event.target.tagName === "DETAILS" && event.type === "turbo:before-morph-element" && event.detail.newElement === undefined) {
    event.preventDefault()
  }
}

This works in about 50% of the cases. Sometimes the details element is still re-created and therefore the open attribute is lost.

I feel that Turbo should somehow cancel out all morphing operations on elements that are part of the lazy-loaded Turbo Frame in order to not have two morphing operations running on the same part of the DOM. For that you likely have to add some sort of information to the Turbo turbo:before-morph-element to add an initiator(?). could be undefined for the page refresh, or pointing to the lazy loaded Turbo frame.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions