Alpine: $watch doesn't work with Array.prototype.push

Created on 15 Apr 2020  路  9Comments  路  Source: alpinejs/alpine

CodePen show's the issue, check the console.log when toggling filters.

https://codepen.io/TomS-/pen/NWGxdzv

Most helpful comment

$watch triggers a function when the value changes (note that, when dealing with objects and arrays, the value is just a reference to the object so $watch only works if you reassign the variable as Ryan suggested).
At the moment, Alpine does not support 'deep' watchers (They would trigger when something inside the object or array changes at any level).
There is an initial PR for it #294 but it hasn't been reviewed yet.

All 9 comments

Hi @FYITom, I'd probably use this.selected = this.selected.concat([item]) instead of this.selected.push(item). The behaviour of .push() and other Array.prototype is a bit temperamental with the reactivity core and the Proxy won't always react to changes and trigger watchers. Explicitely setting a property will definitely work.

I modified your CodePen here (https://codepen.io/ryangjchandler/pen/rNOxyLE?editors=1111) with the changes and the watcher is now reacting.

If you're okay with this, then please close the issue. If you want some further help, just ask, there's always someone here!

Is this a $watch issue? Isn't it a generic reactivity issue on array mutation methods?

Is this a $watch issue? Isn't it a generic reactivity issue on array mutation methods?

Yeah exactly. I've had trouble with .push() before, without the $watcher.

$watch triggers a function when the value changes (note that, when dealing with objects and arrays, the value is just a reference to the object so $watch only works if you reassign the variable as Ryan suggested).
At the moment, Alpine does not support 'deep' watchers (They would trigger when something inside the object or array changes at any level).
There is an initial PR for it #294 but it hasn't been reviewed yet.

$watch triggers a function when the value changes (note that, when dealing with objects and arrays, the value is just a reference to the object so $watch only works if you reassign the variable as Ryan suggested).
At the moment, Alpine does not support 'deep' watchers (They would trigger when something inside the object or array changes at any level).
There is an initial PR for it #294 but it hasn't been reviewed yet.

Yeah exactly that. I think the PR could be tidied up a little before being reviewed / merged too.

Thank you very much for that, makes complete sense to me.

I had the same issue with a Set. Adding or deleting an item does not trigger a watch or set/unset a class in an x-bind:class. After changing the set, I did a selected = new Set(selected) which triggers any updates.

Deep watchers are not supported yet. The watcher triggers only if you reassign the variable but not if you change it's internal state.

I know this is old but this thread just got me out of a four hour hole-of-dev-doom.

Thanks @ryangjchandler for answering and @FYITom for asking (and both working off a Codepen demo).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

piotrpog picture piotrpog  路  3Comments

Calinou picture Calinou  路  4Comments

andruu picture andruu  路  3Comments

zaydek picture zaydek  路  3Comments

haipham picture haipham  路  4Comments