svelte-persistent-store icon indicating copy to clipboard operation
svelte-persistent-store copied to clipboard

Is there a way to stop NaN or undefined being saved in local storage?

Open edjw opened this issue 5 years ago • 1 comments

I'd like to save data in local storage unless that data is NaN or undefined. Is there a way to do that?

I realise this might be a Svelte rather than a svelte-persistent-store question

edjw avatar Sep 07 '20 15:09 edjw

This seems to do the trick (a little SSR setup because it was in a Sapper project):

<script>
  import { writable, get } from 'svelte/store';
  import * as local from 'svelte-persistent-store/dist/local';

  const testInner =
    process.browser
      ? local.writable('test', null)
      : writable(null);

  console.log(testInner);

  const test = {
    subscribe: testInner.subscribe,
    set(value) {
      if (value === undefined || value !== value) return;
      testInner.set(value);
    },
    update(updater) {
      this.set(updater(get(this)));
    },
  };
</script>

<style>
</style>

<p>
  {JSON.stringify($test)}
  {$test === null}
  {$test === undefined}
  <button on:click={() => test.set("foo")}>foo</button>
  <button on:click={() => test.set(null)}>null</button>
  <button on:click={() => test.set(undefined)}>undefined</button>
  <button on:click={() => test.update(value => value ? null: "foo")}>toggle null</button>
  <button on:click={() => test.update(value => value ? undefined : "foo")}>toggle undefined</button>
</p>

Note how setting/toggling to undefined does not work.

I basically take the info about the store contract and the update that's missing there to create a wrapper around a writable store, in this case a persistent one. update is basically copied from this repo; not sure if there's a better way to implement it - note what the Svelte docs say about get.


Edit: This should also be possible using svelte-writable-derived. I haven't tried it and the examples sadly don't show it, but the docs indicate it should work.

Original example:

var jsonStore = writable(`{"I'm a property": true}`);
var objectStore = writableDerived(
	jsonStore,
	(json) => JSON.parse(json),
	(object) => JSON.stringify(object)
);

What should work for you:

var jsonStore = writable(`{"I'm a property": true}`);
var objectStore = writableDerived(
	jsonStore,
	(json) => JSON.parse(json),
	(object, set) => {
		if (object !== undefined) set(JSON.stringify(object));
	},
);

SillyFreak avatar Jan 03 '21 09:01 SillyFreak