Mobx-state-tree: Proper usage of types.optional

Created on 23 Nov 2018  路  3Comments  路  Source: mobxjs/mobx-state-tree


Hi guys! I have a model containing a field as such:

title: types.optional(types.string, ""), // string The title of the user

And when my data comes with { title: null } I get the following error when trying to applySnapshot it into my model:

An error occured while loading this resource TypeError: Cannot read property 'data' of undefined

If I change the code to types.maybeNull(types.string) it works just fine, but I would like empty strings by default.

This is the action that is loading the data:

. . .
          const { data } = yield axios({ url, method, data: body, ...options })
          applySnapshot(self, { users: [...data] })
. . .

I've read this post and none of the alternatives given seem to solve it (except for the suggestion to "pre-process" the snapshot, which honestly just seem like a huge hack to get something simple to work.

Do you guys have any suggestion on what approach to take?

  • [x] I've checked documentation and searched for existing issues
  • [x] I tried the spectrum channel
question should be ready to close stale

All 3 comments

types.optional substituted undefined by the second argument.
If you want to substitute a null value your best bet is to substitute null for undefined in a preProcessSnapshot and back to null in a postProcessSnapshot

Alternatively you can define your title as types.maybeNull(types.string) and create a view that returns empty string when the property is null

views(self => ({
  get normalizedTitle() {
     return self.title || "";
  }
}))

This issue has been automatically marked as stale because it has not had recent activity in the last 10 days. It will be closed in 4 days if no further activity occurs. Thank you for your contributions.

I decided to go forward with the types.optional(types.string(), "") along with pre and postProcessSnapshot route.

  .preProcessSnapshot(snap => {
    const 
      title = snap.title || undefined,
      phone_mobile = snap.phone_mobile || undefined,
      phone_work = snap.phone_work || undefined,
      personal_email = snap.personal_email || undefined,
      alt_email = snap.alt_email || undefined

    return {
      ...snap,
      title,
      phone_mobile,
      phone_work,
      personal_email,
      alt_email,
    }
  })
Was this page helpful?
0 / 5 - 0 ratings