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

Add setState style callback to Onyx.merge() #103

Closed
wants to merge 5 commits into from

Conversation

marcaaron
Copy link
Contributor

Details

cc @roryabraham @aldo-expensify

This adds a setState() style callback to Onyx.get() so that we can remove or overwrite object properties without storing local copies. For now, it is up to whoever uses this feature to make sure they are handling a value that doesn't exist and the type. We won't assume what the value should be only that if you pass a function instead of a value you are handling the possibility that there might not be any value to use at all.

Related Issues

https://github.com/Expensify/Expensify/issues/176419

Automated Tests

Added a small test to verify the change should work

Linked PRs

To Do

@marcaaron marcaaron requested a review from a team as a code owner September 3, 2021 21:22
@marcaaron marcaaron self-assigned this Sep 3, 2021
@marcaaron marcaaron removed the request for review from a team September 3, 2021 21:22
roryabraham
roryabraham previously approved these changes Sep 3, 2021
Copy link
Contributor

@roryabraham roryabraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

I am confused why we have to do Promise.resolve().then(() => keyChanged(key, finalValue));, but that was there before so NAB.

@marcaaron
Copy link
Contributor Author

I am confused why we have to do Promise.resolve().then(() => keyChanged(key, finalValue));, but that was there before so NAB.

Good instinct, but not sure what to do about it at this point. IIRC there's some code in Expensify/App is assuming the keyChanged() update to happen after one or more ticks of the event loop (since before we did not have caching and it happened after a Promise resolves). Rather than try and discover all the places where code might assume this it was decided to move the call inside a Promise that resolves as fast as possible (so kind of like a fancy setTimeout).

@marcaaron
Copy link
Contributor Author

Actually now that I've begun to test this. I'm not sure if it's going to work / might be causing some weird side effects - gonna throw a hold on this for a sec.

@marcaaron marcaaron marked this pull request as draft September 3, 2021 22:11
@marcaaron
Copy link
Contributor Author

marcaaron commented Sep 3, 2021

Ok I think I figured something out. Unsure if we should switch things up.. but just want to note that it's possible using this could lead to weird race conditions if not used carefully. e.g. if you call Onyx.set() but also call Onyx.merge() after then it's possible that one will succeed before the other.

I'm not sure if this is really much different from what would happen if you mixed and matched a set() without a callback with a merge().

@marcaaron
Copy link
Contributor Author

marcaaron commented Oct 26, 2021

Gonna switch this up and start looking into a merge() with a callback instead of a set().

My reasoning is that:

  • set() doesn't work with the mergeQueue and we shouldn't encourage that use for this behavior - which is modifying an existing value.
  • set() should be for setting data and I think not modifying existing data.
  • merge() makes more sense.

Edit: Actually thinking more on this and I don't know if merge or set will really work as expected on these values.

We identified the weird race condition where an Onyx.set() that happens after Onyx.merge() can be overwritten and Onyx.merge() still has a problem where array values do not cleanly get merged.

Will think about it some more.

@marcaaron marcaaron changed the title Add setState style callback to Onyx.set() Add setState style callback to Onyx.merge() Oct 26, 2021
@marcaaron
Copy link
Contributor Author

Gonna close this until we are ready to implement and come to some conclusions here

@marcaaron marcaaron closed this Oct 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants