arrow-js
arrow-js copied to clipboard
Nested template being called unexpectedly
I have a conditionally-included template like this:
const state = reactive({ items: [], index: 0 });
...
${() => hasItem()
? html`
${() => currentItem().loaded !== false
? html`
<img src="${() => currentItem().url}"
@load="${e => onImageLoaded(e, true)}"
@error="${e => onImageLoaded(e, false)}">
${() => currentItem().loaded === null ? loadingAnimation : null}`
: html`<div style="color: red;">Item failed to load</div>`}
<div>Current rating: ${() => currentItem().rating}</div>
</div>`
: loadingAnimation}
...
function hasItem() { return state.items.length > state.index; }
function currentItem() { return hasItem() ? state.items[state.index] : null; }
state
is a reactive object with an array items
and an integer property index
. What surprises me is that sometimes I am hitting a javascript error on this line:
<div>Current rating: ${() => currentItem().rating}</div>
The problem is that currentItem()
is null. However, I would have expected this not to be called because of the hasItem()
conditional. Am I misunderstanding something about how Arrow is supposed to work with conditional templates?
I think the issue here (could be wrong) is arrow doesn’t destroy the previous template but memoizes it for future re-insertion (like <KeepAlive>
) which means effects are still running on it even when it isnt mounted. Probably something we should fix in future iterations.
Makes sense. I do think it would be desirable if the control flow could be respected. For the time being, is there any workaround to force arrow to ditch the template?