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

HAML code with form tag connect controller twice #520

Closed lukasedw closed 3 years ago

lukasedw commented 3 years ago

Bug Report

GitHub application: https://github.com/lukasedw/twice-stimulus

Describe the bug

When you have a form before the controller div using HAML, the stimulus controller is called twice when action-reflex is triggered.

To Reproduce

Using the application go to /foo/index_haml and open the console, the controller 'example' shows log 'Connected', after clicking 'Go!', 'Connected' log (that is in connect of Example controller) is called again and then 'afterCreate' log appear, but in /foo/index_erb this doesn't happen.

Expected behavior

In both templates, connect only once.

Screenshots or reproduction

image

Versions

StimulusReflex

leastbad commented 3 years ago

Hi Lukas! Thanks for reporting this. I can confirm that I am seeing the behaviour you describe... and I am indeed a little confused, but I'll share what I can see. Note that this is 100% a Haml problem, but since it's impacting your attempts to work with SR, we'll do what we can to help.

What's happening is that morphdom is deciding the #example div is being modified, even though so far as I can tell, it has no reason to be updated. I even went into the ERB partial and swapped the order on line 8 so that it looks like <div data-controller="example" id="example"> - just so that the output would be the same for both template engines.

Meld_52PbmRqYvI

What I'm seeing is that apparently Haml lost the plot somewhere along the way wrt generating beautiful markup, which is a shame. I have no idea why your whitespace is being lost in the Haml version.

The weirdest detail I spotted is that in the Haml version, when you view source you see that, on line 20, the data-reflex attribute is set to click-&gt;Example#create. What I don't understand is why (and what) is html encoding your > character into &gt;. Unfortunately, experience suggests that this can't be good!

I agree that this should work and to the best of my knowledge, lots of folks use Haml with SR. I'm going to ask some other folks to take a look-see, too.

KonnorRogers commented 3 years ago

I can confirm I see it disconnecting then reconnecting. But only on the first reflex. All subsequent reflexes do not trigger disconnect + reconnect.

existentialmutt commented 3 years ago

fwiw I checked view source on a HAML/SR app I run and noticed I'm also getting those click-&gt; in data-reflex / data-action attributes. I haven't seen any ill-effects from that but the app also uses selector morphs.

leastbad commented 3 years ago

Regardless of the Stimulus reconnect situation, it is deeply strange that Haml emits &gt; in this way... presumably, that's just one of many substitutions.

  1. It's clearly converted to > by the time it hits the DOM, as evidenced by the Element Inspector.
  2. Why aren't other Haml users seeing this?

The issue isn't so much that running connect again is potentially undesirable (but often could be!)... it's that reinitializing the controller means callbacks aren't possible. NO GOOD

RolandStuder commented 3 years ago

This is our old friend called "differences in whitespace", morphdom gets confused when there are differences in whitespace, as whitespace adds/removes textnodes that weren't there before, therefore confusing morphdom about how to morph some stuff, it thinks is has new nodes therefore replaces some nodes unnecessarily.

But good news: This is fixed in 3.5.0.pre1, so just update to the prerelease version and you @lukasedw are fine. More specifically this was fixed by our wonderful @lmatiolis in https://github.com/stimulusreflex/stimulus_reflex/pull/492