I want to do something like:
open Webapi.Dom;
let addListener = (element) =>
EventTarget.addEventListener("click", onSubscribeClick, EventTarget.asEventTarget(element));
let addOrRemoveListeners = (handler, ()) => {
let elements = Document.querySelectorAll({j|[$subscriptionIdAttr]|j}, document);
Js.Array.forEach(handler, NodeListRe.toArray(elements) |> Js.Array.map(Element.ofNode))
};
let addListeners = addOrRemoveListeners(addListener);
let removeListeners = addOrRemoveListeners(removeListener);
But I get an error in addOrRemoveListeners(addListener);
:
This is:
(Dom.eventTarget) => unit
But somewhere wanted:
(Dom.node) => unit
How should I convert from Dom.eventTarget
to Dom.node
?
Edit: I ended up with this:
let addListener = Element.addEventListener("click", onSubscribeClick);
let removeListener = Element.removeEventListener("click", onSubscribeClick);
let addOrRemoveListeners = (handler, ()) => {
let elements = Document.querySelectorAll({j|[$(subscriptionIdAttr)]|j}, document);
let () =
elements
|> NodeListRe.toArray
|> Array.map(Element.ofNode)
|> Array.to_list
|> List.filter(Js.Option.isSome)
|> List.map(Js.Option.getExn)
|> List.iter(handler);
()
};
let addListeners = addOrRemoveListeners(addListener);
let removeListeners = addOrRemoveListeners(removeListener);
Short answer:
external eventTargetToNode : Dom.eventTarget => Dom.node = "%identity";
An eventTarget
can be almost anything, and there's unfortunately no good way of figuring out what it is. In JavaScript it's simply inferred by the user based on context (It might be possible to carry that context around in a type parameter, but that's off in the future somewhere).
So for the moment you'll have to make an unsafe cast to get what you need.
(BTW, you can use Element.addEventListener
to avoid the cast from element
to eventTarget
)