bejewelled
bejewelled

Reputation: 305

Svelte Custom Stores with Objects: How do I only update one key at a time?

I have the following store: import {writable} from 'svelte/store';

function playerRes(info) {
    const { subscribe, set, update } = writable(info);

    return {
        subscribe,
        add: (amt) => update(n => n + amt),
        sub: (amt) => update(n => n - amt)
    };
}

export const res = playerRes({
    kelp: 0,
    sand: 0
});

I'm trying to edit the add and sub functions so that I can add, say, 5 kelp, or 10 sand at a time, without changing the rest of the object. However, it seems like with this setup, I'm only able to edit the entire object at once. I tried add: (type, amt) => update((n[type]) => (n[type]) + amt) but this threw a bunch of errors. I also tried to call something like res['kelp'].add(5) in my other files, but this didn't work either. How would I go about this?

Upvotes: 0

Views: 1363

Answers (1)

brunnerh
brunnerh

Reputation: 184376

The input will always be the entire object. You can modify individual properties of the store content but you also still have to return the entire object.

Something like:

return {
    subscribe,
    add: (type, amt) => update(n => { n[type] += amt; return n }),
    sub: (type, amt) => update(n => { n[type] -= amt; return n })
};
<button on:click={() => res.add('kelp', 1)}>+ kelp</button>

REPL

Another approach, which does not rely on mutating objects, would be to create a copy with the target property replaced.

That would look like this:

return {
    subscribe,
    add: (type, amt) => update(n => ({ ...n, [type]: n[type] + amt })),
    sub: (type, amt) => update(n => ({ ...n, [type]: n[type] - amt })),
};

REPL

Upvotes: 1

Related Questions