Reputation: 4044
I would like to reset an existing store's values to the defaults. For UX reasons, I don't want to create a new store.
const defaults = {
name: {
value: "",
},
foo: [],
some: {
other: {
data: ""
}
}
};
const store = writable(defaults);
export const myStore = {
subscribe: store.subscribe,
reset: () => {
store.set(defaults);
}
};
The store behaves as expected, with the exception of the reset()
method. Whenever it's called it does not update the store, none of the reactive bindings reflect what should be the default values.
...
$myStore.name.value = "foo";
// foo
myStore.reset();
$myStore.name.value;
// foo
Upvotes: 1
Views: 969
Reputation: 11
Another way -
const defaults = {
name: {
value: "",
},
foo: [],
some: {
other: {
data: ""
}
}
};
const store = writable(defaults);
export const myStore = {
subscribe: store.subscribe,
reset: () => {
store.set(JSON.parse(JSON.stringify(defaults)));
}
};
Upvotes: 0
Reputation: 494
This isn't an issue with Svelte, but with how javascript handles objects. When you assign an object to another variable, it will only assign a reference, and not clone the object. This means that, when you call $myStore.name.value = "foo";
, you are actually updating the same object that is stored in defaults
.
You can observe this by running the code below
let a = {name: ''};
let b = a;
b.name = 'test';
console.log(a); // {name: 'test'}
Since you're using objects inside objects, just destructuring default also won't work, since you'll only get a shallow copy of an object, meaning that you could update $myStore.name
but wouldn't be able to update $myStore.name.value
properly.
To properly copy defaults, you could use structuredClone
, which is available in Chrome 98, Firefox 94 and Node 17. Rewriting your code, it would be something like this:
const store = writable(structuredClone(defaults));
export const myStore = {
subscribe: store.subscribe,
reset: () => {
store.set(structuredClone(defaults));
}
};
Upvotes: 2