#Track all of the keys in an object with useStore & Object.keys

7 messages · Page 1 of 1 (latest)

jaunty zodiac
#

I'm currently writing my second Qwik app, a calculator, when I encountered this problem and was wondering if this is a good pattern to use or not. I have a well sized object that keeps track of my user input. I need to display that input on the screen whenever it changes.

After refactoring and rethinking my code, I decided that I had to track each of my object's key individually since tracking the object with no named keys did not work .

  useTask$(({ track }) => {
    // this does not log/track at all
    track(() => mathOperation);
    console.log("im tracking!!!");
    display.value = getDisplayOfMathNode(mathOperation);
  });

However, since I did not want to have 5 different tracks all based on the same object, I decided to opt for something I was 90% sure it wasn't going to work:

  useTask$(({ track }) => {
    // this does log/track :)
    track(() => Object.keys(mathOperation));
    console.log("im tracking!!!");
    display.value = getDisplayOfMathNode(mathOperation);
  });

I have rechecked the documentation of both track and useStore and neither mentions this pattern for tracking all of the keys in an object. This seems to me to be a shame because it feels like a very intuitive solution.

If someone more experienced with Qwik could answer this question that would be very helpful since I'm still very early on this project. I also would happily file a PR to update the docs so that they mention this pattern if other (hopefully more experienced) users find it useful too.

undone jolt
#

If you just want to execute the callback in useTask$ everytime the store changes (a key changes, a value changes). Then you just need to call track(myStore).

This would work ```tsx
import { component$, useStore, useTask$ } from '@builder.io/qwik';

function randomString() {
return (Math.random() * 1000).toFixed(0)
}

export default component$(() => {
const myStore = useStore<Record<string, string>>({
first: "value"
});

useTask$((ctx) => {
ctx.track(myStore);
console.log(JSON.stringify(myStore))
})

return <>
<button onClick$={() => myStore[randomString()] = randomString()}>
Add key to store
</button>
</>;
});


Link to playground: https://qwik.builder.io/examples/introduction/hello-world/#v=1.2.13&f=Q0o0Jubm2BKNDrzKBbPAxRrehAQPb1AZmp8LDUyUgNbwTSzJ0IPIA2W0FAwNDAw09Ury3TIrUlM0DDSBQU1UgoSEbm4l2H3AAIa3DoKAlWRRig2k1aEDbX3Y2WmANCkopGUWFZdYKSgB83BpqhJQCJR8gRS8OaCRXFIBtwRoTUmFHriy14BaBVQOFkdqYXgF%2B%2FvpQezJTKuEK9QEmw4yHJZ5oJEAaUYhWg%2FVEF9B9UWjBl4s0G%2BoIrWwmHVMSVHITq1UKAG2DEA6oVEMbaUBecDoHs2fQzV%2FAgA
Qwik

No hydration, auto lazy-loading, edge-optimized, and fun 🎉!

#

But if you REALLY only want to track when the keys change, not when the values of the keys change (which is rarely the case, but might be what you specifically need?). Than the track(() => Object.keys(myStore)) works.

azure sequoia
# undone jolt But if you REALLY only want to track when the keys change, not when the values o...

What about the case when the store is a 'key value' store.. Meaning the number of keys and values are not defined, it is kinda dynamic. Example would be adding a variant to a product cart. If i have a variantStore to store variant as {[key:string]: Variant} . the number of keys and associated values are dynamic depending on user selection from the available product variant. In this case, would tracking just the store run the userTask$?

undone jolt
#

Take a look at my example the Record<string, string> is what you're asking for

#

Record<string,string> = { [key: string]: string }