I’m new to AlpineJS. I have some production knowledge of React and some basics of Vue. But one of the things I’m not getting about AlpineJS and I did not find a direct answer to this from any of the documentation or tutorial videos on AlpineJS, that’s why I’m asking this. It’s obviously my lack of knowledge, but I’m afraid, that’s true for every newcomer. 🙂
Suppose, I have the following code (summarized):
<div x-data="{ array1 = [], array2 = [], total = 0 }">
<!-- ✅ Success: Get user input and populate array1 here -->
<!-- ✅ Success: Get user input and populate array2 here too -->
<button x-show="$store.total === 0; console.log("👉 ", $store.total)">
Do Something
</button>
</div>
<script>
const myFunc = (array1, array2, total) => {
// Reference: https://stackoverflow.com/q/76607996/1743124
const hash = array2.reduce((h, s) => {
h[s] = (h[s] || 0) + 1;
return h;
}, {});
array1.map(function(s) {
if(hash[s] && hash[s]--) {
console.log("🏌️♂️ total ", total);
Alpine.store('total', total--); // 🟥 QUESTION IS HERE.
console.log("🕴️ total-- ", total);
return '✅' + s;
} else {
return s;
}
});
}
</script>
The myFunc
code is taken from this SO thread.
As you can see that I achieved some of the things. My question is about How can I update the total
state from inside the function myFunc
and that can be available outside the function for general use?
As in React, we can easily update a state like the below:
// REACT JS EXAMPLE FOR A CONTRAST.
const [total, setTotal] = useState(0);
// Somewhere setTotal(500);
const myFunc = () => {
setTotal(total--); // under certain condition within a 🔄️ loop
return true;
};
Here, though the function is returning some other thing, the state is been updated using a setState directive, but we can get the updated value of total
anywhere outside.
How can I do a similar thing in AlpineJS? I understood that it can be done using the Store global, but it’s not working as expected. The console.logs inside the function were showing exactly what I expected, a 0
(zero) when it should be. But the console.log($store.total)
is giving me 1
⚠️:
What am I doing wrong here?
Is this a desired effect of the Store global in AlpineJS?
PS. The event that I’m working with is @keyup
when all the things are getting fired.
2
Answers
Although I don’t understand what
total
represents and how you get it before passing it tomyFunc
I can see that you are mixingx-data
with store and also initializing store inside a loop. Issue is probably caused by these things.You can move it all in store (data and functions). And then show the data in HTML and call functions on events. Something like components in Vue.js where you have data and methods and then use it in
<template>
.I would do it something like this:
total
will go to negative here when conditions are met but you can easily pass param tomyFunc
with whatever data you need and work with it.Full example is here https://jsfiddle.net/z2w0p7m3/
From all I gather, you’re simply confused as to why
total
is 1 within your$store
, even though it logs "0" one line later. That’s simple JS operator logic, which applies to multiple coding languages.Let me explain: You have a "post-" and "pre-decrement" operator (also for increment). It’s basically whether the operator is before (pre) or after (post) the variable, and the difference is the order of operations. In the pre operation, the operator is first executed, and then the variable is evaluated. In the post operator, the variable is first evaluated, and then the operator is executed.
Example:
Basically what is happening, is that you’re storing the value of
total
, and then you’re decrementing it. If you’re expecting the stored value to be 0, you should use pre-decrement (--total
).You can read more details about it here.