joshnuss / svelte-persisted-store

A Svelte store that persists to localStorage

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How should one ensure default state is persisted to local storage before any updates?

Holf opened this issue Β· comments

For example, if I create this store:

export const createSimpleTextStore = (simpleText = "Some simple text") => {
    const simpleTextStore = persisted<string>("simpleText", simpleText);
    
    return {
        simpleTextStore,
    };
};

... and then use it thusly:

<input type="text" placeholder="Enter simple text" bind:value={$simpleTextStore} />

I find that, although my input is populated with the text "Some simple Text", it is not written to Local Storage until I prompt an update by editing the input value.

The reason I ask this is that I have two different stores each of which relate to each other. The default state of these may change on subsequent releases and I can foresee a situation when one has been persisted and the other has not, leading to inconsistencies between the two.

I can take control of persisting this default state myself but wondered if there was a more canonical approach.

Thank you for a great library; it is proving to be very useful.

Thanks @Holf!

It's a good point. The state should be persisted during initialization.

I'm create a PR to fix this.

πŸŽ‰ This issue has been resolved in version 0.5.0 πŸŽ‰

The release is available on:

Your semantic-release bot πŸ“¦πŸš€

This change is reverted by #199

I feel it's a better default to only write changes.

We can always force the write using some custom JavaScript, ie localStorage.setItem(key, initialValue)

Would you be open to re-introducing this behaviour as an option?

Hi Holf!

I'm wondering if many people need this? I just want to make sure the options are broadly applicable.

The alternative is to write if yourself, like this:

if (!localStorage.getItem('mykey')) {
  localStorage.setItem('mykey', defaultValue)
}

This can be further extracted into a new "builder" function:

import { persisted } from 'svelte-persisted-store'

export function persistedWithDefaultWrite(key, initialValue, options = {}) {
  if (!localStorage.getItem('mykey')) {
    localStorage.setItem('mykey', defaultValue)
  }
  
  return persisted(key, initialValue, options)
}

I am also open to adding it if many people request it.

Hi, thanks for the reply, and the suggestion.

Yes, I can easily do this. I guess it was just that the functionality to so all this was already in there, so near, and yet so far. πŸ˜„

But I completely appreciate the desire for a focussed package that doesn't have a complex API trying to do everything under the sun. Besides, the scenario I was concerned about really is a rather unlikely edge case.

Thanks for understanding!

If anyone else is running into this issue, please comment below and I'll consider re-opening if there are many requests.

I ran into the same issue and was a bit confused, but I guess this behavior makes sense as in most cases the initial value will be static. I would still appreciate if this would be an option (persistInitialValue).

Anyway here is my edge case:
I assign users who have not yet created an account a random username:

const anonymousUsername = persisted('anonymousUsername', randomName())

And with the current logic the username changes on every refresh unless the user changes their name.

@DevLeoko thanks for the example!

I think a new option should be added. I'd probably call it write, example:

persisted(key, value, {
   write: 'changes' // default value, writes to storage only when changes happen
})

persisted(key, value, {
   write: 'eager' // write to storage during first instantiation, if key is empty
})

Hi @joshnuss thanks for your prompt answer.

Yes, an option like that would be great. I like the wording.
I'd be happy to make a quick PR for this if you'd like

Thanks @DevLeoko,

Definitely open to a PR!