Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

createViewModel doesn't respect { deep: false } #170

Closed
sheerun opened this issue Jan 10, 2019 · 11 comments
Closed

createViewModel doesn't respect { deep: false } #170

sheerun opened this issue Jan 10, 2019 · 11 comments

Comments

@sheerun
Copy link

sheerun commented Jan 10, 2019

It happens with mobx-utils 5.1.0:

const { observable } = require('mobx')
const { createViewModel } = require('mobx-utils')
const model = observable.object({ unit: null }, {}, { deep: false })
model.unit = { foo: [1,2,3] }
Array.isArray(model.unit.foo)
// => true
model.unit
// => { foo: [ 1, 2, 3 ] }
Array.isArray(view.unit.foo)
// => true
view.unit = { foo: [1,2,3] }
const view = createViewModel(model)
Array.isArray(view.unit.foo)
// => false
view.unit
// => { foo: [Getter/Setter] }
view.unit.foo
// => ObservableArray [Array] {}

It happens that I pass model to library that tries to do isArray check on some internal array of unit which mobx converted to ObservableArray. I think createViewModel could preserve shallowness to prevent such errors.

@sheerun
Copy link
Author

sheerun commented Jan 10, 2019

Even worse: after doing view.submit() the original model.unit.foo becomes observable which should never be

@sheerun
Copy link
Author

sheerun commented Jan 11, 2019

@mweststrate I there any way to know that provided mobx observable has been created shallow?

@ItamarShDev
Copy link
Member

ItamarShDev commented Jan 26, 2019

isn't the note from the docs says it would? @sheerun

You may use observable arrays, maps and objects with createViewModel but keep in mind to assign fresh instances of those to the viewmodel's properties, otherwise you would end up modifying the properties of the original model. Note that if you read a non-dirty property, viewmodel only proxies the read to the model. You therefore need to assign a fresh instance not only the first time you make the assignment but also after calling reset() or submit().

@sheerun
Copy link
Author

sheerun commented Jan 26, 2019

It would be true for deep observed objects, but shoudn't be the case for { deep: false } observables

@ItamarShDev
Copy link
Member

Looking at the code, it seems that this should be an observable by design.
Not sure its a bug...

@mweststrate

@sheerun
Copy link
Author

sheerun commented Feb 24, 2019

It should be an observable, but in my case it should be shallow observable, not deep one.

@mweststrate
Copy link
Member

I think this is a bug indeed, and that the modifiers should be preserved. @sheerun would you mind creating a PR with some unit tests demonstrating the erroneous behavior and verifying a potential fix?

@mweststrate mweststrate added the bug label Mar 4, 2019
@sheerun
Copy link
Author

sheerun commented Mar 4, 2019

I can but first I need an answer to my previous question because I couldn't find how, and without this it's not possible to implement any fix:

Is there any way to know that provided mobx observable has been created shallow?

@urugator
Copy link
Contributor

Hacky inefficient solution:

function isShallow(thing) {
  if (isObservableObject(thing)) {
    return !isObservable(thing.$mobx.defaultEnhancer([]));
  }
  if (isObservableArray(thing)) {
    return !isObservable(thing.$mobx.enhancer([]));
  }
  if (isObservableMap(thing)) {
    return !isObservable(thing.enhancer([]));
  } 
  return false;  //?
}

[
  // deep
  observable({}),
  observable([]),
  observable(new Map()),
  // shallow
  observable({}, {}, { deep: false }),
  observable([], { deep: false }),
  observable(new Map(), { deep: false })
].forEach(thing => console.log(isShallow(thing)));

@mweststrate
Copy link
Member

I think this PR requires some additional reflection methods in MobX first, a proposal is welcome (on that repo)

@mweststrate
Copy link
Member

Closing for inactivity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants