htmx:targetError with conditional hx-trigger
I have the following polling mechanism:
<div id="poll-messages"
hx-get="./receive"
hx-trigger="every 1s [document.querySelector('#messages #typing-indicator') !== null] queue:none"
hx-target="#messages #typing-indicator"
hx-swap="outerHTML scroll:bottom"
hx-disabled-elt="#chat-form button"
class="is-hidden"
>
Which polls an endpoint when #typing-indicator is present, and replaces the typing indicator with the response.
However, when #typing-indicator is absent from the DOM, a htmx:targetError is logged to console every second:
htmx:targetError [email protected]:1:27520
R https://unpkg.com/[email protected]:1
ae https://unpkg.com/[email protected]:1
fe https://unpkg.com/[email protected]:1
he https://unpkg.com/[email protected]:1
wt https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
(Async: setTimeout handler)
ct https://unpkg.com/[email protected]:1
timeout https://unpkg.com/[email protected]:1
The GET request to the receive endpoint is not executed as expected.
I've moved the polling behaviour to the #typing-indicator itself, which avoids running into this issue (and probably makes more sense anyway). Still, I was expecting hx-target to be only relevant after the request had completed.
Yeah your workaround is probably the simplest solution. The issue you found was because htmx event filters do not currently support the keyword 'null' properly.
hx-trigger="every 1s [document.querySelector('#typing-indicator')] queue:none"
This would have worked fine however
The issue is that htmx event filters are designed to not just be generic javascript but also handle detecting variables that could be in either window or event scope to allow you to do simpler [key='Enter'] style filters without having to prefix event. or window. But this makes it treat some built in JS reserved words as variables causing issues.
Here is the htmx function involved:
function isPossibleRelativeReference(token, last, paramName) {
return SYMBOL_START.exec(token.charAt(0)) &&
token !== 'true' &&
token !== 'false' &&
token !== 'null' && // this line could be added for example
token !== 'this' &&
token !== paramName &&
last !== '.'
}
Ah, good to know, thanks!