Search code examples
javascripthtmx

HTMX event listener only triggered once


I have the following div in my DOM whose sole purpose is to make a GET request when the "send-message" event is emitted:

<div
    hx-get="https://catfact.ninja/fact" 
    hx-trigger="send-message from:document"
    hx-swap="none"
></div>

I'm expecting GET https://catfact.ninja/fact to be fired off every time the "send-message" event is emitted.

Instead, the request is only fired the first time the event is emitted since the element was loaded. Every subsequent event emission does not trigger the div's HTMX event listener.

As a sanity check, I have this listener log to the console every time the event gets emitted:

document.addEventListener("send-message", () => {
    console.log("send-message event emitted in document");
});

EDIT: minimum reproducible example

<!DOCTYPE html>
<html>
<head>
    <script src="https://unpkg.com/[email protected]" integrity="sha384-L6OqL9pRWyyFU3+/bjdSri+iIphTN/bvYyM37tICVyOJkWZLpP2vGn6VUEXgzg6h" crossorigin="anonymous"></script>
</head>
<body>
    <script type="text/javascript">
        const sendMessageEvent = new Event("send-message");
        const handleKeypress = (event) => {
            if (event.key === "Enter") {
                event.preventDefault();
                document.dispatchEvent(sendMessageEvent)
            }
        };
        document.addEventListener("keypress", handleKeypress);
        document.addEventListener("send-message", () => {
            console.log("send-message event emitted in document");
        });
    </script>
    <div 
        hx-get="https://catfact.ninja/fact" 
        hx-trigger="send-message from:document"
        hx-swap="none"
    />
</body>
</html>

Solution

  • The problem is that "sendMessageEvent" event is still the same event every time it gets emitted. So when the HTMX listener is triggered, it already stored the div in a handledFor array for that event and therefore treats the action as already handled.

    The solution is just to emit a new event every time by doing document.dispatchEvent(new Event("send-message"));.