mobxjs / mobx-state-tree

Full-featured reactive state management without the boilerplate
https://mobx-state-tree.js.org/
MIT License
6.94k stars 641 forks source link

Cannot compose late models #1922

Closed Ghirigoro closed 1 year ago

Ghirigoro commented 2 years ago

Bug report Using late references in compose fails at runtime. My understanding is that late types can be used as aliases for the type they refer to, but that doesn't seem to be the case here.

NOTE: This may not be a bug but I cannot find any reference to this limitation in the docs

Sandbox link or minimal reproduction code

const Base = types.model({ x: types.number });
const Derived = types.compose(
  types.late(() => Base),
  types.model({ y: types.number })
);

// ERROR: [mobx-state-tree] expected mobx-state-tree model type as argument 1, got [object Object] instead 
const test = Derived.create({ x: 1, y: 2 }); 

Describe the expected behavior It should create an instance of the Derived model without errors.

Describe the observed behavior It fails in creating an instance of the Derived model with the error: [mobx-state-tree] expected mobx-state-tree model type as argument 1, got [object Object] instead 

patrickschmelter commented 2 years ago

have you found a solution?

Ghirigoro commented 2 years ago

@patrickschmelter Sorry I haven't and given the level of response this is getting I'm guessing there isn't one ;)

diegochavez commented 2 years ago

Hi @Ghirigoro @patrickschmelter I'm trying to understand your use case. The documentation explains that types.late is intended to do recursive implementations,

Regarding compose you can only use it as adding types.model https://mobx-state-tree.js.org/API/#compose

Check this example I did of the use for types.late and compose https://codesandbox.io/s/elastic-moser-oj5mum?file=/src/store.tsx:121-126

Ghirigoro commented 2 years ago

@diegochavez my memory is a bit hazy on the specifics (I've since moved away from the approach that required this) but if I remember correctly I was writing a DSL to define content for our app which would be used to generate JSON schemas and MST models. The DSL was pretty open ended so you could find yourself with complicated types that were composed of types that had recursive (or transitively recursive) references. Rather than try to unsnarl those and try to figure out which types required late references in composition I made ALL references in composition late. And that's where I ran into the problem.

Ghirigoro commented 1 year ago

No sorry

On Aug 19, 2022 at 5:51 AM, <Patrick Schmelter @.***)> wrote:

have you found a solution?

— Reply to this email directly, view it on GitHub (https://github.com/mobxjs/mobx-state-tree/issues/1922#issuecomment-1220480456), or unsubscribe (https://github.com/notifications/unsubscribe-auth/AADDEWXZMYZ3LO3SVBHRMQDVZ5KJHANCNFSM5ZJJEOLA). You are receiving this because you authored the thread.Message ID: @.***>

mikeKlech commented 1 year ago

I think you should wrap to types.late the whole model. Like this:

const Derived = types.late(() => types.compose(
  Base,
  types.model({ y: types.number })
));
coolsoftwaretyler commented 1 year ago

Hey @Ghirigoro - did @mikeKlech's solution here work for you? Did you find any other solution to the problem?

Ghirigoro commented 1 year ago

@coolsoftwaretyler I had long abandoned that approach by the time that @mikeKlech made his suggestion, so I haven't tried it and I didn't find any other solutions.

coolsoftwaretyler commented 1 year ago

Thanks for the follow up!

For folks who end up here with similar problems, I put together a quick CodeSandbox comparing the original snippet in the issue, and the solution proposed by @mikeKlech. Wrapping everything in types.late does seem to remove the errors, although it's unclear to me if that would have solved the original issue.

I'm going to close this out for now, but please open another issue if anyone has follow up problems.