-
Notifications
You must be signed in to change notification settings - Fork 75
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 waitForCollectionCallback to keysChanged #167
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, maybe this test can be split up better for testing, because it's becoming a bit unclear to me what it's doing. Each test should have a very clear GIVEN/WHEN/THEN, but right now this has GIVEN/AND/WHEN/THEN/WHEN/THEN/AND 😅
Could you try making the test more clear to test each case independently?
Sure thing! I split the test into two, one to test Ready for another review! |
lol, ignore my first deleted comment, I missed the |
Left 2 small comments, overall looks good! |
Updated! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave the merge to @tgolen so he can review
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those tests looks great now! Thank you
I wanted to question some assumptions, and my disclaimer is, it's been a long time since I've worked on that connect() code, so I don't fully remember what's feasible or not.
// THEN we expect the callback to have called twice, once for the initial connect call + once for the collection update | ||
expect(mockCallback.mock.calls.length).toBe(2); | ||
|
||
// AND the value for the first call should be null since the collection was not initialized at that point |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it seem weird to anyone else that:
- There would be two calls
- The first call passes
null
- The second call is really what we want with
waitForCollectionCallback=true
?
Is it possible for us to remove that first call? What is the value in having the call triggered with null
before the collection has been "initialized"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is expected since we want to initialize that key's value to null
, since we are connecting to that key, we just don't have a value for it. We leave it up to the subscriber to decide what to do with a null value.
This happens here before we run any callback subscriber logic. I think it would make sense to keep the behavior consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to what @luacmartins said :), I would also prefer to avoid exceptions and let the subscriber handle that. What if null
is a valid value and we want to be notified about it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, those are good points. I think it would be a change in behavior that could make other bugs in the process, so this was more of an exploratory question. Let's leave it as-is!
I'm kind of confused about this decision though I understand the need that it fills and appreciate the improvement. It almost feels like this should be the default behavior based on how subscribing to a collection key works when there is a Just curious if anyone agrees that it would be more consistent to have something like: Onyx.connect({key: ONYXKEYS.COLLECTION.REPORT}, callback: (allReports) => {...}) because that's what this code would do: withOnyx({
allReports: {key: ONYXKEYS.COLLECTION.REPORT},
})(MyComponent); And if we want individual member values returned then we should do something like Onyx.connectToCollectionMembers({key: ONYXKEYS.COLLECTION.REPORT, callback: (value, key) => {...}}); Last, I'm just not really sure about the name |
Also unsure if this is known (and apologies in advance if I'm wrong about this) but the data returned changes based on whether
Lines 330 to 332 in 1f58aa5
But keysChanged() (triggered when mergeCollection is used) will always return the collection
Lines 260 to 267 in 1f58aa5
Kind of unpredictable, no? How do you know which method is used and what to expect in the callback? |
For the entire collection to be read out of Onyx into memory. @marcaaron Can you clarify what you are proposing? It sounds like you're implying some kind of proposal (which looks good to me so far), but I'm just not clear what you're suggesting. That's a good point about merge vs mergeCollection. |
I'm proposing that we make the behavior of
That would be more consistent and not require us to use a flag like |
Ah, got it. That makes sense to me 👍 |
I agree with your proposed solution @marcaaron! Let's do it! |
cc @tgolen
Details
In #163, we added a new param
waitForCollectionCallback
toOnyx.connect
that waits for the collection to be read and triggers the callback only once. However, we forgot to add that param tokeysChanged
which means that the callback is being triggered for each key when we update the collection.This PR fixes that and ensures that the callback is called only once when we update the collection.
Related Issues
#163
Automated Tests
Added in
onyxTests
Linked PRs
Expensify/App#10051