ionic-team/stencil-store

Expose `oldValue` in `onChange`

simonhaenisch opened this issue · 3 comments

Stupid example:

interface Foo {
  value: string[];
}

export const { state, on, onChange } = createStore({ foo: { value: ['foo'] } });

Currently I have to do

on('set', async (key, newValue: Foo, oldValue: Foo) => {
  if (key !== 'foo') {
    return;
  }

  // crazy complex logic that compares the values and does something
  if (Array.from(new Set(newValue)).join() !== Array.from(new Set(oldValue)).join()) {
    await updateServer(newValue);
  }
}

This involves filtering the key and manually specifying the types for newValue and oldValue.

I'd prefer to be able to do

onChange('foo', async (foo, oldFoo) => {
  if (Array.from(new Set(foo)).join() !== Array.from(new Set(oldFoo)).join()) {
    await updateServer(foo);
  }
}

(with type inference)

There is no simple fix for this. We can expose the old value when the change is because of a set but not when the change is coming from a reset.

Ah ok thanks for the info, I wasn't aware that onChange is called for a reset as well. In my case it's actually important that it only runs on set so I'll use on instead.

I suppose you could extend and export your own function if you don't care about the reset:

export const listenTo = (prop, callback) => on('set', (key, newValue, oldValue) => { 
  return key === prop && callback(newValue, oldValue)
});