Check if Turbo is loaded in JS

I built an “autosubmit” Stimulus controller that checks for a query param in the URL and - if found - calls requestSubmit() on a form. The problem is that this happens so quickly that Turbo is not loaded yet, thus the form is submitted without Turbo.

How can I check in JS whether Turbo is loaded yet, and if it isn’t, listen for an event, so I can call requestSubmit() when I’m sure Turbo will handle the form submission?

You can wait for the turbo:load event to be fired: Turbo Reference

Beware that it also fires on every subsequent page visit that Turbo handles but considering your scenario, I would guess that you probably want this as well?

Thanks for the hint! The problem is that I don’t really want to wait for an event, but I want to check at a certain point whether Turbo is loaded.

I guess, I could wait for the event, set a flag somewhere and check for that flag later.
The way I solved it for now is to check if the Turbo constant is defined, and if not, wait for it:

waitForConstant(name, interval = 100, timeout = 10000) {
  return new Promise((resolve, reject) => {
    const startTime = Date.now()

    function checkConstant() {
      if (typeof window[name] !== "undefined") {
        resolve(window[name])
      } else if (Date.now() - startTime >= timeout) {
        reject(new Error(`${name} is not defined within the timeout period.`))
      } else {
        setTimeout(checkConstant, interval)
      }
    }

    checkConstant()
  })
}

this.element.querySelectorAll("select, input[type='text'], input[type='checkbox'], input[type='radio']").forEach(input => {
  input.addEventListener("change", () =>
    this.waitForConstant("Turbo")
      .then(() =>
        this.element.requestSubmit()
      )
  )
})

ohk, this information is very usefull

1 Like