So I gave it a try at implementing a way of removing an event listener after adding it to a node.
A problem I ended up facing was that by definition, you can only remove an event listener from a nodeif you keep around a reference to the function that you added to said node.
Given that the wrapper around DOM.addEventListener expects a (e: Event) => IO<void> as the event listener to be mounted on the node but the underlying DOM implementation of addEventListener expects a (e: Event) => void before mounting the listener to the node, we first have to turn the function inside-out and execute the IO... but this means that the listener we end up mounting on the node is actually a different function from what had originally been passed to our DOM.addEventListener!
Practically speaking, this means that:
declare const someFunction: (e: Event) => IO<void>
window.addEventListener("click", _ => someFunction(_)())
window.removeEventListener("click", _ => someFunction(_)())
/* ^-- this will never work, the function mounted on window click is NOT someFunction */
The cleanest way I found of dealing with this problem was making it so that DOM.addEventListener also returns an IO<void> to be used to remove that same event listener.
This lets me create a private reference to the "unwrapped" (e: Event) => IO<void> and thus have a consistent way of creating aremoveEventListener that will actually work.
I also thought about possibly returning just the "private" listener as IO<(e: Event) => void> but I felt like this type definition didn't really make much sense...
I guess that we could also return some sort of State to keep around all the "right" reference to the listeners that are actually being mounted on a node, but that might be more trouble than it is worth it I guess?
So I gave it a try at implementing a way of removing an event listener after adding it to a node.
A problem I ended up facing was that by definition, you can only remove an event listener from a
node
if you keep around a reference to the function that you added to saidnode
.Given that the wrapper around
DOM.addEventListener
expects a(e: Event) => IO<void>
as the event listener to be mounted on the node but the underlying DOM implementation ofaddEventListener
expects a(e: Event) => void
before mounting the listener to the node, we first have to turn the function inside-out and execute theIO
... but this means that the listener we end up mounting on the node is actually a different function from what had originally been passed to ourDOM.addEventListener
!Practically speaking, this means that:
The cleanest way I found of dealing with this problem was making it so that
DOM.addEventListener
also returns anIO<void>
to be used to remove that same event listener. This lets me create a private reference to the "unwrapped"(e: Event) => IO<void>
and thus have a consistent way of creating aremoveEventListener
that will actually work.I also thought about possibly returning just the "private" listener as
IO<(e: Event) => void>
but I felt like this type definition didn't really make much sense...I guess that we could also return some sort of
State
to keep around all the "right" reference to the listeners that are actually being mounted on a node, but that might be more trouble than it is worth it I guess?