mobxjs / mobx-state-tree

Full-featured reactive state management without the boilerplate

Home Page:https://mobx-state-tree.js.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error "assertion failed: the creation of the observable instance must be done on the initializing phase"

Sinled opened this issue · comments

I am recieving this error:

[mobx-state-tree] assertion failed: the creation of the observable instance must be done on the initializing phase

when i am tring to apply snapshot to node that has array of nested nodes.

  • I've checked documentation and searched for existing issues
  • I've made sure my project is based on the latest MST version
  • [-] Fork this code sandbox or another minimal reproduction.
    Tried to make reproduaction, but strangely enough, it fails only inside my application

Describe the observed behavior
I'have a small unit test, that fails inside my application, but strangely enough, works inside library, which is used inside application

describe('Apply snapshot', () => {
    const ItemBase = types.model({});

    const ItemModel = model({
        modelName: 'Item',
        modelType: ItemBase,
    });

    const ParentModelBase = types.model({
        items: types.array(ItemModel),
    });

    const ParentModel = model({
        modelName: 'Parent',
        modelType: ParentModelBase,
    });

    const Container = types
        .model({
            collection: types.map(ParentModel),
        })
        .views((self) => {
            return {
                hasInstance(record: any): any {
                    return self.collection.has(`${record.id}`);
                },

                getModelInstance({ id }: any) {
                    return self.collection.get(`${id}`);
                },

                createInstance(data: any): any {
                    return self.collection.put(ParentModel.create(data));
                },
            };
        })
        .actions((self) => {
            return {
                updateInstance(data: any) {
                    const modelInstance = self.getModelInstance(data);

                    applySnapshot(modelInstance, data);
                    modelInstance.setupInitialSnapshot();

                    return modelInstance;
                },
            };
        })
        .actions((self) => {
            return {
                createOrUpdateModelInstance(data: any): any {
                    if (self.hasInstance(data)) {
                        return self.updateInstance(data);
                    } else {
                        return self.createInstance(data);
                    }
                },
            };
        });

    const SNAPSHOT = {
        id: 84,
        items: [{ id: 929 }, { id: 922 }, { id: 940 }, { id: 150 }],
    };

    it('can apply snapshot twice', () => {
        const root = Container.create();

        const item = root.createOrUpdateModelInstance(SNAPSHOT);

        expect(item.items[0]._clientId).toBe('929');

        expect(() => root.createOrUpdateModelInstance(SNAPSHOT)).toThrow('asf');
    });
});

model here - is a small factory, that lives in separate package and adds common behaviour, such as id property, and _clientId ``identifier property

when i run this test inside library - it works fine. I am out of ideas what might be causing this.
As i understand exception is thrown when mst is trying to apply snapshot to destroyed entity, but i've tried to add beforeDestroy and beforeDetach hooks to all models, and these hooks are never called, so probably models are not in destroyed state

Did you find a solution for this @Sinled? It's happening for me in production code.

In my case it's a virtualized list that is adding+removing elements to the DOM. But it's acting on a copy of the MobX state data, so I don't see why mobx-state-tree is throwing this error.

@gdbroman sadly no,
at the moment I see this error only during development so I can live with it

Hey @Sinled - can you say more about:

model here - is a small factory, that lives in separate package and adds common behaviour, such as id property, and _clientId ``identifier property

How is your model function doing that? Do you have a reproducible example that uses your library (or something similar to it) and demonstrates the same error behavior?

Hey @Sinled - I'd be happy to help out more with this bug if you can provide a reproduction. But if you're OK with the state of things, I will close this out if I don't hear from you in the next two weeks or so.

Hi @coolsoftwaretyler, it seems i've found solution for my problem. It was some strange behaviour of pnpm and rushjs monorepo.

I found out that this error was thrown only in applications in monorepo that didn't have mobx as explicit dependency, and were relying on transient dependency from my lib, that used mst and mobx.
Adding mobx to package.json solved problem.

But i am still not sure why this particular error has been thrown

Thanks for the follow-up @Sinled!