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

Change of behavior in ObservableMap.replace when using intercept in Mobx v4 #2253

Closed
Lmzd opened this issue Jan 9, 2020 · 13 comments · Fixed by #2287
Closed

Change of behavior in ObservableMap.replace when using intercept in Mobx v4 #2253

Lmzd opened this issue Jan 9, 2020 · 13 comments · Fixed by #2287

Comments

@Lmzd
Copy link

Lmzd commented Jan 9, 2020

Version

Mobx: 4.13.1
Node: v13.2.0

Issue

Only in mobx4

Following the changes in #1980 and #2003, visible in v4.13.1. We are facing a difference in the replace method of ObservableMap in v4.13.0.

When we intercept a change on a given property of the Map and cancel it (return null), the value is not set in the Map (expected) but the internal keys array of the Map is updated with the name of the intercepted property.

Change the version of mobx to 4.13.0 to see the previous behavior
Code to reproduce

@urugator
Copy link
Collaborator

urugator commented Jan 9, 2020

Could you try this version?
EDIT: ah nevermind that won't do the trick

Notes (to self):
V5 is most likely affected as well.
Check if there are other operations that delegates to this.set/this.delete
Test also a removal of a key.
Provide internal _set/_delete with outcome rather than re-checking keys of _data.

@GLabat
Copy link

GLabat commented Jan 9, 2020

Hi thanks for your reply.

We checked MobX 5 and the code is the same as in v4.13.0, so before the change on replace.

The thing is that the internal keys of the map does not take into account a possible cancellation during interception. So we have to somehow find a way to call the setter of the given prop which triggers the interceptor handler. Depending on whether the change has to be performed or not, the keys should be updated accordingly.

@urugator
Copy link
Collaborator

urugator commented Jan 9, 2020

@FredyC It seems that a fix of #1980 for V5 isn't present in the master. Do you have a clue why? (only V4 is fixed)
EDIT Is this: #2058 (comment) where it ended? Or is the PR somewhere?

@mweststrate
Copy link
Member

@GLabat / @Lmzd would you guys be interested in making a PR? Even a unit test to protect against regressions would be super useful, as apparently we have one :)

@Lmzd
Copy link
Author

Lmzd commented Jan 9, 2020

@mweststrate Yes sure

@danielkcz
Copy link
Contributor

danielkcz commented Jan 9, 2020

It seems things got somehow messy in merging.

The PRs were #2057 (V5) and #2058 (V4). But then #2057 (comment) happened and V5 were being reverted and I am lost there if the issue was somehow resolved or not 🤷‍♂

@urugator
Copy link
Collaborator

urugator commented Jan 10, 2020

Considering we want to respect the order of the keys in the replacement map:
If I cancel key deletition via interceptor, what is the expected position of the (non-deleted) key in the final key array?

@mweststrate
Copy link
Member

mweststrate commented Jan 10, 2020 via email

@urugator
Copy link
Collaborator

Like this?
[1,2,3] keep 2 [5,6,7] => [5,2,6,7] ?
[1,2,3] keep 3 [5] => [5,3] ? (original 3 is out of bounds)

@mweststrate
Copy link
Member

mweststrate commented Jan 10, 2020 via email

@urugator
Copy link
Collaborator

urugator commented Jan 10, 2020

So that would be at the beginning of the key array preserving the original (non-deleted) key order...

Similar situation with set ... if I cancel set the key should also stay at the beginning of the key array, rather than respecting it's new position:
[1,2,3] (cancel set 1) [3,2,1] => [1,3,2]
Correct?

In summary whatever is cancelled should appear at the beginning of the key array in the original key order...

EDIT: Just for clarification, it's:
[original keys] (interception) [replacement keys] => [resulting keys]

@mweststrate
Copy link
Member

yes, in other words, all original ordering is preserved, regardless the ordering in the updates. Only for items that were not present already, their relative order in the updates is relevant. (So the only effective way to reorder is to separately first remove items, and then re-add them in the desired order, otherwise all existing items stay where they are).

@lock
Copy link

lock bot commented Apr 19, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs or questions.

@lock lock bot locked as resolved and limited conversation to collaborators Apr 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants