Skip to content

Commit bffc528

Browse files
keithamuskoddsson
andcommitted
fix: bind controllers before custom connectedCallback behavior
If a controller synchronously dispatches events in its connectedCallback, `data-action` handlers register the event too late, because connectedCallback itself is a synchronous callback, while `MutationObserver` is tasked. This changes `bind` to be called _before_ custom `connectedCallback` behavior so that any events dispatched in a `connectedCallback` are captured by the `data-action` handler, making for a simpler understanding of `data-action` handlers. By making this change we allow developers to not have to internalise the idea of dispatching events during Synchronous or Asynchronous tasks/microtasks. Developers can simply dispatch an event without worrying if it was synchronous or not. Co-authored-by: Kristján Oddsson <koddsson@gmail.com>
1 parent 550468c commit bffc528

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

src/controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ export function controller(classObject: CustomElement): void {
1616
this.toggleAttribute('data-catalyst', true)
1717
autoShadowRoot(this)
1818
initializeAttrs(this)
19-
if (connect) connect.call(this)
2019
bind(this)
20+
if (connect) connect.call(this)
2121
}
2222
defineObservedAttributes(classObject)
2323
register(classObject)

test/controller.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,25 @@ describe('controller', () => {
1616
expect(instance.hasAttribute('data-catalyst')).to.equal(true)
1717
expect(instance.getAttribute('data-catalyst')).to.equal('')
1818
})
19+
20+
it('binds controllers before custom connectedCallback behaviour', async () => {
21+
controller(class ControllerBindOrderElement extends HTMLElement {})
22+
controller(
23+
class ControllerBindOrderSubElement extends HTMLElement {
24+
connectedCallback() {
25+
this.dispatchEvent(new CustomEvent('loaded'))
26+
}
27+
}
28+
)
29+
30+
const instance = document.createElement('controller-bind-order')
31+
chai.spy.on(instance, 'foo')
32+
document.body.appendChild(instance)
33+
34+
const sub = document.createElement('controller-bind-order-sub')
35+
sub.setAttribute('data-action', 'loaded:controller-bind-order#foo')
36+
instance.appendChild(sub)
37+
38+
expect(instance.foo).to.have.been.called(1)
39+
})
1940
})

0 commit comments

Comments
 (0)