I want a function invoked when the Query completes. The callback function passed to my Query onCompleted should be invoked
The onCompleted callback was not invoked (I used a simple console.log function)...
The Query works, the data is available, just not seeing onCompleted
Create a simple Query component - just a graphql query - no Subscription
Set a simple onCompleted={()=>console.log('onCompleted')}
variables={{ email: ${email} }}
onCompleted={()=>console.log('The Query onCompleted callback was invoked')}>
{({ loading, error, ...result }) => (
<div>
<MemberWithEmailResults
{...result}
loading = {loading}
error = {error}
email = {email}
/>
</div>
)}
</Query>
Version
I was able to get this to work using https://codesandbox.io/s/xr6vxpw9xo - so obviously this is just something that I am doing wrong.
Closing the issue
Same issue. My react-apollo version is also 2.1.4. When I upgrade to 2.1.11 the issue is gone.
I think we should reopen the ticket, because the issue still exists. I'm having it with react-apollo v2.1.11 and in @johnreynoldsventure's example above nothing is logged to the console, so onCompleted is not fired.
I'm reopening this issue in response to yantakus' request... My installation is working fine, but I never really did track down why.
I'm guessing that it's a dependency issue of some sort based on how wonky it seems to be.
I'm also having this problem using react-apollo ^2.0.1. Using the following code, neither the onCompleted or onError callback functions fire.
export default compose(
connect(mapStateToProps, propsMapping),
graphql(query, {
options: ({ changeId, currentPage }) => ({
variables: {
changeId: changeId,
pageNumber: currentPage
},
onCompleted: (data) => {
console.log('test')
console.log(data)
},
onError: (error) => {
console.log(error)
}
})
}),
networkWrapper
)(MyComponent)
Same here for "react-apollo": "^2.1.11" but with the <Mutation /> component 馃槩
Update: it turns out that for my case, my use of both refetchQueries and onCompleted together caused the Mutation component to be gone as a result of refetching (i.e. setting the UI state into loading makes the <Mutation /> component itself to disappear) even before it can run the onCompleted callback. No idea if it is intended to do so but when I stop refetching the aforementioned query, the onCompleted callback is called again. If order of refetchQueries and onCompleted is deterministic I am not so sure.
related to: #2201
I believe that my problem has to do with the react lifecycle of my Query components. onCompleted is not called unless I explicitly use client.resetStore in componentWillUnmount.
I'd like advice from the moderator on whether to close this issue - since it may in fact be react rather than apollo.
@escapiststupor Exactly same issue. Do you have any progress for this issue?
@escapiststupor
That's very helpful and makes a lot of sense... If the "subscriber" unmounts before the query or mutation completes, then it certainly can't invoke the callback.
This would also explain why the behavior isn't deterministic - It's a race condition between the completion of the query/mutation and component's lifecycle.
I'll take another look at my circumstance to see if I've constructed a race condition.
Same here for
"react-apollo": "^2.1.11"but with the<Mutation />component 馃槩Update: it turns out that for my case, my use of both
refetchQueriesandonCompletedtogether caused theMutationcomponent to be gone as a result of refetching (i.e. setting the UI state into loading makes the<Mutation />component itself to disappear) even before it can run theonCompletedcallback. No idea if it is intended to do so but when I stop refetching the aforementioned query, theonCompletedcallback is called again. If order ofrefetchQueriesandonCompletedis deterministic I am not so sure.related to: #2201
setting notifyOnNetworkStatusChange={true} has worked for me
Just for information, I resolved my case with using update props. My problem was that it seems <Mutation> component with refetchQueries does not trigger onCompleted callback, So I use update props to callback instead of onCompleted. It does work fine to me. I hope this can help you guys.
I also hope this bug fixed soon.
@mattdamon108 could you please provide an example?
@yantakus here the code snippets is...
<Mutation
mutation={SET_RATE}
variables={{
newRate: JSON.stringify(this.state.newRate),
handler: "add"
}}
refetchQueries={[
{
query: GET_RATES,
variables: {
uid: this.props.USER_ID,
queryParams: JSON.stringify({
something: here
})
}
}
]}
update={() => this._notify("SAVED!", "success")}
>
{cudRate => <button onClick={() => cudRate()}>SAVE</button>}
</Mutation>
@mattdamon108 The topic is about Query component, it doesn't have update method. But it has updateQuery: https://www.apollographql.com/docs/react/essentials/queries.html#render-prop, maybe we can use it for this purpose. Have to try.
@yantakus Yes, I knew that this is about Query component issues. But @escapiststupor 's issues is exactly same problem that I had. Like you said, for Query component, updateQuery could be a solution.
notifyOnNetworkStatusChange={true}
This actually calls it twice when you visit it a second time (reading from the cache)
I'm not seeing a clear case here or reproduction. If I have it wrong please point me to a codesandbox and I'll reopen.
I can definitely add that onCompleted does NOT work on Query component or composed components. I've tried updating all possible dependencies and still nothing.
same here. It does not work
For those following this issue, if the <Mutation> component is unmounted as a result of refetchQueries, the onCompleted prop will never be called.
This is by design, or at least it's intentional:
The early return above is there to prevent calling this.setState when Mutation unmounts. In which case, onComplete will never be called.
Unless I'm missing something here, by changing the logic of onMutationCompleted a little bit, it looks like it's possible to invoke the user-provided onComplete even when the Mutation unmounts.
The question really is: should onComplete be called at all after a Mutation unmounts?
I'm not seeing a clear case here or reproduction.
@rosskevin one example/use-case I have is a logout button that invokes a mutation, which re-fetches a query to propagate this change to the rest of the app (e.g. removing references to the currently logged-in user). On that mutation, we have an onComplete to redirect to the login page after both _a successful logout mutation_ AND _a successful refetch_ . With the current implementation, this is not possible because as soon as refetchQueries is finished, the logout button will unmount and the redirect will never happen.
I managed to get this to work on a fork, so I'm happy to open a PR!
@wsmd happy to look at a PR - if nothing more than to further the discussion and have a better understanding of the use case.
It is hard to think that an unmounted component would have callbacks called, but I'm open to understanding arguments against that expectation. PR will help flesh this out.
Thanks @rosskevin! I have a PR now #2710
FYI, a workaround is to use the mutate function coming into the render prop, which returns a promise which can then be reacted to with then/finally or doing async/await style. Instead of depending on onCompleted to be called for an unmounted component, the promise result can be used.
mutate({...variables}).then(result => onCompleted(result))
@dennishansen if you see carefully at the title of the thread, it is about Query component, not about Mutation. Your solution seems to be very useful for Mutation, but unfortunately it's not applicable to Query.
Accidently closed by merging the PR.
For the record, #2710 was addressing https://github.com/apollographql/react-apollo/issues/2293#issuecomment-424964210, https://github.com/apollographql/react-apollo/issues/2293#issuecomment-428593113, https://github.com/apollographql/react-apollo/issues/2293#issuecomment-451780184, and https://github.com/apollographql/react-apollo/issues/2293#issuecomment-429175263.
I'll update the PR description.
onCompleted is not called when the query is resolved from the cache rather than from network
Thanks Mike... that makes sense, but I'd suggest that it's somewhat counter intuitive.
I'd expected the method to be invoked whenever the query completes, regardless of where the data is retrieved from and regardless of whether or not the retrieved data matches the previous result.
I haven't looked carefully at the documentation, but suspect that this behavior is not made clear.
@mcmar I figured as much. But that makes it a bug, not just counter intuitive.
@mschipperheyn How about "counter intuitive to the point of being a bug" ;-)
@johnreynoldsventure @mschipperheyn I agree 100%. I agree that this is undocumented behavior/bug. I'm not justifying it. Just explaining that's the way it works today and we should open a PR to fix it. The code's in this file for anyone smart/brave/gutsy enough to fix it:
https://github.com/apollographql/react-apollo/blob/master/src/Query.tsx
I implemented a temporary hack/workaround in my own code where I check something 1 time only in the render method. Definitely not ideal, but it did technically fix the issue, so my users are happy
you say potato... ;-)
apollo-client: 2.5.1
<Query 1 fetchPolicy="network-only">
<Query 2 fetchPolicy="network-only">
<Query 3 fetchPolicy="network-only">
onComplete dosn't work on the 2nd and the 3rd queries.
If I replace network policy in 2 and 3 to fetchPolicy={"cache-and-network"} - works
A lot of the onCompleted issues mentioned here have been addressed as of react-apollo 2.5.3. If anyone is still encountering issues, please report them in a new issue (ideally with a small runnable reproduction). Thanks!
Having the same issue with @apollo/react-hooks :-(
Having the same issue with
@apollo/react-hooks:-(
Also facing this issue with @apollo/react-hooks@^3.1.2 with SSR. Did you find any workaround?
Same issue, please reopen this
Same issue here.
Same issue with hooks reopen or new issue?
@michaeltrim If you can create a runnable reproduction (saved in a github repo or codesandbox) then it might be better to open a new issue. The Apollo team is currently hard at work on apollo-client v3 and probably won't have much time to respond to issues until next month. Your problem is more likely to be seen if it's in an open issue.
I am also facing the same issue for both onError and onCompleted with @apollo/react-hooks.
Please reopen the issue.
I think @apollo/react-hooks call onCompleted only if you provide id for update your localstate
Let me explain with a exemple using useLazyQuery
const GET_MY_FIRSTNAME = gql`
{
me {
firstname
}
}
`;
const [getFirstname] = useLazyQuery(GET_MY_FIRST_NAME, {
onCompleted(data) {
/* Never call 馃憥 */
}
const GET_MY_FIRSTNAME = gql`
{
me {
id
firstname
}
}
`;
const [getFirstname] = useLazyQuery(GET_MY_FIRST_NAME, {
onCompleted(data) {
console.log(`Hey my name is ${data.me.firstname} 馃憤` )
}
I do not what happing here. Everyone is reporting, it's not working but still, the issue is resolved. I am also facing the same issue my "react-apollo": "^3.1.3", and "react": "^16.12.0",. I'm not using hooks becuase it was old code.
@mumarm45
as @destpat explaining
I think @apollo/react-hooks call onCompleted only if you provide id for update your localstate
if you are missing id field in your query, adding id will fix the problem. (fixed mine)
What I had to do was install regenerator-runtime and waait and give my component time to update
import regeneratorRuntime from "regenerator-runtime";
import wait from "waait";
it("renders component with construct", async () => {
const root = create(<MockedProvider addTypename={false} mocks={mocks}><Component /></MockedProvider>);
await wait(500);
expect(root.toJSON()).toMatchSnapshot();
})
Most helpful comment
onCompletedis not called when the query is resolved from the cache rather than from network