xaviergonz / mobx-keystone

A MobX powered state management solution based on data trees with first class support for Typescript, support for snapshots, patches and much more
https://mobx-keystone.js.org
MIT License
549 stars 25 forks source link

getRefsResolvingTo after loading from snapshot #56

Closed sisp closed 5 years ago

sisp commented 5 years ago

There seems to be a problem with getRefsResolvingTo after loading the state from a snapshot. Specifically, I'm retrieving backreferences in a computed property which uses getRefsResolvingTo and all works fine with the "original" state, but when I load the state from a snapshot, the array of backreferences returned by the computed property is empty.

I've created a test case that demonstrates the problem, but I haven't been able to find its cause.

import { computed } from 'mobx';
import {
  fromSnapshot,
  getParent,
  getRefsResolvingTo,
  getSnapshot,
  model,
  Model,
  prop,
  Ref,
  registerRootStore,
  rootRef,
} from 'mobx-keystone';

test('getRefsResolvingTo after loading from snapshot', () => {
  @model('#56/Root')
  class Root extends Model({
    a: prop<A>(),
    b: prop<B>(),
  }) {}

  @model('#56/A')
  class A extends Model({}) {
    @computed
    public get bs(): B[] {
      return Array.from(getRefsResolvingTo(this), ref => getParent<B>(ref)!);
    }
  }

  @model('#56/B')
  class B extends Model({
    a: prop<Ref<A>>(),
  }) {}

  const aRef = rootRef<A>('aRef');

  const a = new A({});
  const b = new B({ a: aRef(a) });
  const root = registerRootStore(new Root({ a, b }));
  expect(root.a.bs).toHaveLength(1);
  expect(root.a.bs[0]).toBe(b);

  const newRoot = registerRootStore(fromSnapshot<Root>(getSnapshot(root)));
  expect(newRoot.a.bs).toHaveLength(1); // ERROR: length is 0
});
xaviergonz commented 5 years ago

Thanks! will be fixed in 0.25.2

xaviergonz commented 5 years ago

Out now

sisp commented 5 years ago

Confirming that the problem is also solved in my real app. Thanks!