stimulusreflex / stimulus_reflex

Build reactive applications with the Rails tooling you already know and love.
https://docs.stimulusreflex.com
MIT License
2.28k stars 172 forks source link

Not calling afterReflex if you remove action element inside reflex with morph #365

Closed WozniakMac closed 3 years ago

WozniakMac commented 3 years ago

Bug Report

Describe the bug

When you call the reflex to remove clicked element from dom, afterReflex callback won't ba called.

I suspect it's because element in dispatchLifecycleEvent on stage finalize is null. Because of this, my loading spinner is not stopping. image image

To Reproduce

show.html.erb

<div id="to-remove">
  <button type="button" data-reflex="click->TestReflex#remove"></button>
</div>

test_reflex.rb

class TestReflex < ApplicationReflex
  def remove
    morph "#to-remove", ""
  end
end

application_controller.js

import Turbolinks from 'turbolinks'
import { Controller } from 'stimulus'
import StimulusReflex from 'stimulus_reflex'

export default class extends Controller {
  connect() {
    StimulusReflex.register(this)
  }

  beforeReflex(element, reflex) {
    console.log("beforeReflex", element, reflex);
  }

  afterReflex(element, reflex) {
    console.log("afterReflex", element, reflex);
  }
}

My example with modal https://github.com/hopsoft/stimulus_reflex_expo/compare/master...WozniakMac:bug-repoduction-remove-action-element-reflex#diff-f0f6e190c54120fc0d7c11be7de363c7035cb8e9ce35fa1a5a8ac3a48881814cR21-R23

Expected behavior

I should be able to call afterReflex even if the element is removed.

Screenshots or reproduction

image

Versions

StimulusReflex

External tools

Browser

leastbad commented 3 years ago

Sadly, the premise of your issue is flawed in the context of how SR is designed and (as you have confirmed) how it works.

Please understand that I am not happy to tell you this; I'd far prefer that this was a bug.

However, the two things you're wanting to do are indeed mutually exclusive; you can either replace an element or raise an event from a Stimulus controller instance on that DOM element... but not both. That's because the instance of the Stimulus controller you're expecting to hear from will no longer exist.

Hopefully, this confirmation will free you to try other design approaches in your application.