relay-hooks: Warning: RelayConnectionHandler: Unexpected after cursor `WyJuYXR1cmFsIiwxMF0=`, edges must be fetched from the end of the list (`WyJuYXR1cmFsIiwyMF0=`).
I got another strange bug I need to squash before I can carry on with other tasks.
On page http://my-app/my-posts there is a clickable element with onClick handler:
(event) => {
event.preventDefault();
history.push('/my-posts'); // same page as current value in browser address bar
}
On the same page there is a component with Load More button. When clicking on that button, it calls loadMore function returned by usePagination hook. It’s almost identical to the usePagination example.
If you press the Load More button without doing anything else, it loads another set of results from the graphql server without problems. It also works if you navigate to another page, and then back (doesn’t matter if using browser’s back button, or using another history.push call, it still works). But for some reason it fails after trying to navigate to the same page, you’re already at, for example you’re on page http://my-app/my-posts and call history.push(‘/my-posts’) and then press the Load More no new items are rendered and I get the following warning:
index.js:1 Warning: RelayConnectionHandler: Unexpected after cursor `WyJuYXR1cmFsIiwxMF0=`, edges must be fetched from the end of the list (`WyJuYXR1cmFsIiwyMF0=`).
I see that the graphql request and response are identical in both cases - when it works fine, and when it fails.
Here is the relevant stacktrace:
console.<computed> | @ | index.js:1
-- | -- | --
| r | @ | backend.js:1
| printWarning | @ | warning.js:30
| push../node_modules/fbjs/lib/warning.js.warning | @ | warning.js:51
| update | @ | RelayConnectionHandler.js:127
| (anonymous) | @ | RelayPublishQueue.js:216
| _getSourceFromPayload | @ | RelayPublishQueue.js:212
| (anonymous) | @ | RelayPublishQueue.js:242
| _commitData | @ | RelayPublishQueue.js:238
| run | @ | RelayPublishQueue.js:178
| _processResponse | @ | RelayModernQueryExecutor.js:315
| _handleNext | @ | RelayModernQueryExecutor.js:263
| (anonymous) | @ | RelayModernQueryExecutor.js:207
| _schedule | @ | RelayModernQueryExecutor.js:178
| _next | @ | RelayModernQueryExecutor.js:206
| next | @ | RelayModernQueryExecutor.js:94
| next | @ | RelayObservable.js:565
| (anonymous) | @ | RelayNetworkLayer.js:55
| Promise.then (async) | |
| subscribe | @ | RelayNetworkLayer.js:54
| (anonymous) | @ | RelayObservable.js:474
| _subscribe | @ | RelayObservable.js:610
| subscribe | @ | RelayObservable.js:296
| Executor | @ | RelayModernQueryExecutor.js:85
| execute | @ | RelayModernQueryExecutor.js:43
| (anonymous) | @ | RelayModernEnvironment.js:224
| _subscribe | @ | RelayObservable.js:610
| subscribe | @ | RelayObservable.js:296
| (anonymous) | @ | RelayObservable.js:233
| _subscribe | @ | RelayObservable.js:610
| subscribe | @ | RelayObservable.js:296
| (anonymous) | @ | fetchQueryInternal.js:114
| _subscribe | @ | RelayObservable.js:610
| subscribe | @ | RelayObservable.js:296
| (anonymous) | @ | RelayObservable.js:211
| _subscribe | @ | RelayObservable.js:610
| subscribe | @ | RelayObservable.js:296
| (anonymous) | @ | RelayObservable.js:369
| _subscribe | @ | RelayObservable.js:610
| subscribe | @ | RelayObservable.js:296
| (anonymous) | @ | RelayObservable.js:211
| _subscribe | @ | RelayObservable.js:610
| subscribe | @ | RelayObservable.js:296
| push../node_modules/relay-hooks/lib/FragmentPagination.js.FragmentPagination._fetchPage | @ | FragmentPagination.js:346
| push../node_modules/relay-hooks/lib/FragmentPagination.js.FragmentPagination.loadMore | @ | FragmentPagination.js:225
| loadMore | @ | useOssFragment.js:94
Thanks for looking into it.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 51 (28 by maintainers)
Commits related to this issue
- #28, use the resolver just created in the callback and not the reference to the old one. — committed to relay-tools/relay-hooks by morrys 5 years ago
- Merge pull request #29 from relay-tools/fix-28 #28, use the resolver just created in the callback and not the refere… — committed to relay-tools/relay-hooks by morrys 5 years ago
check this
https://babangsund.com/relay_environment_methods/
and
https://babangsund.com/relay_environment_methods_2/
It’s easy mistake to make, only 1 letter difference 😃
WyJuYXR1cmFsIiw_x_MF0 WyJuYXR1cmFsIiw_y_MF0
sorry 😃 they seemed to me the same 😄
WyJuYXR1cmFsIiwxMF0 WyJuYXR1cmFsIiwyMF0
can you share more code?
https://github.com/relay-tools/relay-hooks/releases/tag/v1.2.7
The final test did not pass … another change was needed.
https://github.com/relay-tools/relay-hooks/releases/tag/v1.2.7
Let me know if everything works, that I still have some time in the afternoon 😃
I was sure we would arrive at the solution: D your test case was fundamental (it is better that we do not say this to @sibelius ) 😃
Now release version 1.2.6
I close the issue after you’ve tried the new version ok? 😃
Yep, this fixes it for me.
Thank you! 🎉
Found the problem 😃 https://github.com/relay-tools/relay-hooks/blob/master/src/useOssFragment.tsx#L102 In the callback there is the reference to resolver and not to res. Then it used the old disposed resolver 😃
I have to do more tests 😃
But you can already try using this:
Thank you so much for trying to get it resolved before you need to go.
Here is the repo as promised: https://github.com/jazblueful/loadmore-rerender
yours is good news;) from tomorrow to monday i’m on vacation, i can watch it but don’t try it … I hope that we can resolve It today;)
I wrote a unit test to reproduce the bug (should have done it way sooner):
The last assertion fails. It looks like it’s caused by rerendering the component after refetching the same data. I will extract the test and all the relevant code into a separate repo tomorrow for you to play with.
The situation is too strange, it seems that old data is recovered in the callback and data updated in the onNext function, as if there were two different stores, and from the information you gave me it all seems to work properly.
At the moment I can only ask you to recreate the error in a project where I can try or you have to investigate the situation more, adding console.log in the classes that I have indicated to you, and trying to understand what changes when you push (tried to avoid the push if you are already on the current page?).
Can you even try to change this? https://github.com/relay-tools/relay-hooks/blob/master/src/useOssFragment.tsx#L85-L87
in this way:
const [result, setResult] = useState<ContainerResult>(newResolver());You sent the diff of the data not of the resolver 😄
The store “seems” correct … Could you do the diff of the serialized object “resolver” here? https://github.com/relay-tools/relay-hooks/blob/80c7203ee21c4a8b9a186ef506812761628e4ba8/src/useOssFragment.tsx#L102
It might be useful to make the diff between the store content in these two scenarios at this point
diff
Could you summarize the operations you do when you detect the warning and when it works?
Moreover, you could debug in these two points in both cases.
https://github.com/relay-tools/relay-hooks/blob/master/src/FragmentPagination.ts#L471
https://github.com/relay-tools/relay-hooks/blob/master/src/useOssFragment.tsx#L102
request = environment.retain(operation.root);when unmount the component (or before re-invoking the fetchQuery):request.dispose()maybe @sibelius can better point you to some articles.
Surely you should manage the dispose of the previous query correctly. So as to maintain a more consistent situation.
Then I can advise you to log what is rendered and what is published in the store (publish function of the store).
I try to respond to the warning: the first query is executed, updates the store but does not refresh the UI, the second is executed but recovered from the cache (network) and when it updates in the store the warning is returned because it finds the data from the first query.
The real question is why the UI in the first query is not updated.
What do you say?
1 thing I forgot to mention is that I need to press
Load Morebutton twice for the warning to be printed on the console.On first click, graphql query is sent and correct response received, but the UI is not updated with data from the response and nothing is printed to the console.
On second click, no query is sent, the UI is not updated, but a warning is printed out to the console.