Svelte: Docs: Add an example of modifying complex store data

Created on 19 Jun 2019  路  10Comments  路  Source: sveltejs/svelte

People seems to be asking at regular intervals about how to update complex data in a store and, while it is relatively straight forward, we could add an example somewhere. Maybe in the tutorial.

stores examples tutorial

Most helpful comment

I can't seem to find any info/examples anywhere on the Internet about the best practice for doing something equivalent to hierarchical/namespaced state management with Svelte v3 stores. It seems n>0 depth is not supported but I cannot find an alternative, other than just having a multitude of top-level stores for every value, which is rather spaghetti-ish.

In particular, I found it surprising that updating a property on an object in a store triggers the reactivity cycle for the whole store. This seems like a pretty big footgun and I feel like the documentation doesn't do enough to warn about this.

I would appreciate it if anyone could post a tiny paragraph on how to handle hierarchical state. Are we supposed to have dozens/hundreds of stores, even for related values?

All 10 comments

This would be helpful. Plus, also add something about the RxJS support that was introduced in https://github.com/sveltejs/svelte/issues/2549

Another important aspect is how stores can be used with local or remote databases. For instance, if using IndexedDB are stores still necessary? Stores seem to have a lot of uses including being a wrapper for a XState Interpreter instance.

Having a store exhibit page that brings together store usages along with mini tutorials sounds good to me.

I think it's a good idea.

Maybe an example with a custom store with immerjs produce drafts?

And maybe an example of subscribing and saving changes to localStorage and reading from localStorage on startup?

Would be great. As well as a discussion about data and state in Svelte and how Stores are best used to model a Svelte app. Happy to help with editing.

Just an example with local storage in my usage. May be useful to someone:

function lsWritable(key, type) {
    let initialValue = localStorage.getItem(key);
    if (type == 'numeric') {
        initialValue = Number(initialValue);
    }
    const { subscribe, set } = writable(initialValue);

    return {
        subscribe,
        set: (value) => {
            localStorage.setItem(key, value);
            return set(value);
        },
    };
}

And then:

export const userName = lsWritable('userName');
export const userAge = lsWritable('userAge', 'numeric');

I can't seem to find any info/examples anywhere on the Internet about the best practice for doing something equivalent to hierarchical/namespaced state management with Svelte v3 stores. It seems n>0 depth is not supported but I cannot find an alternative, other than just having a multitude of top-level stores for every value, which is rather spaghetti-ish.

In particular, I found it surprising that updating a property on an object in a store triggers the reactivity cycle for the whole store. This seems like a pretty big footgun and I feel like the documentation doesn't do enough to warn about this.

I would appreciate it if anyone could post a tiny paragraph on how to handle hierarchical state. Are we supposed to have dozens/hundreds of stores, even for related values?

Redux is a simple set of APIs and its architecture is very clearly articulated. Yet the Docs are extensive!

Redux dedicates an entire site to documentation and teaching.

Additionally, there are numerous articles by the authors about the design of Redux, the best ways to use it, alternative ways to use it and, importantly, how not to use it.

I think that the motivation of wanting to be a very flexible library is could result in a fantastic ecosystem.

But holding back on expressing the motivations and intent behind Svelte's design choices and providing clear guidance on the best patterns to use (and what not to use) may inhibit adoption.

I think @nodefish hits it on the head. Responses and guidance to his and others' questions could be kept informal and less prescriptive (via official blog articles) while evolving the discussion and documentation.

If Svelte had a good home for maintaining persistent, searchable and easily discoverable discussions the progression of body-of-knowledge could be:
Chat > Forum > Blog > Docs.

In response to @MVSICA-FICTA regarding indexedDb I have found that for indexedDb it is probably a good idea to save your db connection object to a Svelte store like:

export const objAppDbConn = writable(); // example within the store.js

... then in your App.svelte use something like the following to save the connection:

var openRequest = indexedDB.open(strAppDbName, 1);

openRequest.onupgradeneeded = function(e) {
  $objAppDbConn = e.target.result;   // set Svelte store to db connection
...

...otherwise if you switch between components you will lose the connection to indexedDb. I'm sure it probably depends on your app architecture but for me the Svelte store was crucial to maintain connection to indexedDb.

If I'm not wrong, the only way to deal with tree-like object in store is to wrap the whole tree in a single store, at least currently.

Nesting stores won't work, because once you drill into the tree in the template, you would want to do things like obj.$nestedStore, or somehow create nestedStore first (in the template part, not script part) and then call $nestedStore, both of which are not supported by svelte.

Wrapping the whole tree in a single store does have the downside that any property change causes the whole tree to be checked for changes.

I checked svelte's store's RFC, Real World demo, TodoMVC demo, official tutorial and API doc. None of which seem to demonstrate how to deal with such complex object in store. I also asked on SO, haven't got any answers yet .

If updating the tutorial is still a long shot, would it be possible to shed some light with some short reply here? @pngwn?

Another downside with single-store design is that if you have a recursive tree like the one used in the doc for <svelte:self>, and you have different classes that represent files and folders, updating a property in the file or folder class must also notify the whole store something has changed.

This makes the classes very hard to be self-contained.


Edit:

Just realize that you could pass nested store as an attribute to components to solve the syntax issue. It does somewhat couple store structure with component structure , but makes it possible to break a tree object down to small stores.

Though I've not yet looked in-depth; it may be worth examining https://github.com/Budibase/budibase for some ideas as there does seems to be extensive use of stores.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AntoninBeaufort picture AntoninBeaufort  路  3Comments

st-schneider picture st-schneider  路  3Comments

Rich-Harris picture Rich-Harris  路  3Comments

lnryan picture lnryan  路  3Comments

sskyy picture sskyy  路  3Comments