[SOLVED] Turbo_stream not connecting stimulus controllers

UPDATE: I change to Firefox and it worked, so I reinstalled Chrome and now it’s working. So it appears it was some weird bug with the MutationObserver within the last version of Chrome

Hey all.

I have no idea what could I be missing here, but will really love your help.

When rendering a turbo stream the streamed html has some data-controller attributes on it. But the controllers are not connecting.

This is my controller code, check the part when the save was not successful. I’m just appending a flash partial.

  def create
    authorize current_user, :super_admin?
    @onboarding = "Onboarding::Step#{onboarding_params[:step]}".constantize.new(onboarding_params)

    if @onboarding.save
      respond_to do |format|
        format.turbo_stream
        format.html {
          return redirect_to companies_path, notice: 'Company created' if @onboarding.last_step?
          render :new
        }
      end
    else
      respond_to do |format|
        flash.now[:alert] = "Something went wrong while setting up the new company, please try again"
        format.turbo_stream { render turbo_stream: turbo_stream.append(:flash, partial: 'shared/flashes'), status: :unprocessable_entity }
        format.html {
          render :new, status: :unprocessable_entity
        }
      end
    end
  end

The flash partial looks like this

<% if notice %>
  <div class="z-50 w-fit transition duration-150 bg-green-100 rounded-lg p-4 text-sm text-green-800 absolute bottom-4 left-4 mr-8 flex justify-between"
       data-controller="alert"
       data-alert-wait-time-value="2000">
    <p class="font-medium flex">
      <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-green-400" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
      </svg>
      <span class="pl-3"><%= notice %></span>
    </p>
    <button class="pl-16 text-sm font-bold flex justify-end items-center" data-action="click->alert#dismiss">
      <svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
      </svg>
    </button>
  </div>
<% end %>

<% if alert %>
  <div class="z-50 w-fit transition duration-150 bg-red-100 rounded-lg p-4 text-sm text-red-800 absolute bottom-4 left-4 mr-8 flex justify-between"
       data-controller="alert"
       data-alert-wait-time-value="2000">
    <p class="font-medium flex">
      <svg xmlns="http://www.w3.org/2000/svg"  class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
      </svg>
      <span class="pl-3"><%= alert %></span>
    </p>
    <button class="pl-16 text-sm font-bold flex justify-end items-center" data-action="click->alert#dismiss">
      <svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
      </svg>
    </button>
  </div>
<% end %>

As you can see it has a data-controller="alert" that is in charge of removing the alert after some time

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static values = { waitTime: { type: Number, default: 1000 } }

  connect() {
    this.timeouts = [window.setTimeout(() => this.dismiss(), this.waitTimeValue)]
  }

  disconnect() {
    this.timeouts.forEach((timeout) => window.clearTimeout(timeout))
  }

  dismiss() {
    this.element.classList.add("-translate-x-full")
    this.timeouts.push(window.setTimeout(() => this.element.remove(), 140))
  }
}

But the turbo stream doesn’t connects the stimulus controller, so the alert gets rendered but it stays in the DOM for ever.

Any ideas on what is happening.

I’m using ESBUILD with Rails 7 and here is my package.json file

{
  "name": "app",
  "private": "true",
  "dependencies": {
    "@hotwired/stimulus": "^3.0.1",
    "@hotwired/turbo-rails": "^7.1.1",
    "@tailwindcss/forms": "^0.4.0",
    "autoprefixer": "^10.4.2",
    "el-transition": "^0.0.7",
    "esbuild": "^0.14.21",
    "flatpickr": "^4.6.9",
    "plotly.js-dist": "^2.10.1",
    "postcss": "^8.4.6",
    "slim-select": "^1.27.1",
    "tippy.js": "^6.3.7",
    "wordcloud": "^1.2.2"
  },
  "scripts": {
    "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds",
    "build:css": "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/style.css"
  },
  "devDependencies": {
    "tailwindcss": "^3.0.23"
  }
}

And last, but, maybe helpful this is the output of Stimulus debugger after clicking next with invalid data, you can see that no other controller is connected after the :unproccesable_entity response.

1 Like

Using browser dev tools > network, can you confirm the app loads this specific controller?

Thanks you!. I already found it was a chrome issue! See update section in the post.

1 Like

This is crazy, I’m glad you found it and google indexed your response, otherwise I would drive myself nuts looking for the answer.

REINSTALL CHROME … who would thought about that… THANKS!

1 Like