Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Apr 13, 2023. It is now read-only.

Conversation

wsmd
Copy link
Contributor

@wsmd wsmd commented Jan 6, 2019

/related #2293 (Query onCompleted not invoked)

See #2293 (comment), #2293 (comment), #2293 (comment), and #2293 (comment)

The issue

When passing both onCompleted and refetchQueries to a Mutation that un-mounts as a result of refetchQueries, onCompleted will never be called.

Consider the following example:

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 onCompleted to redirect to the login page after both a successful logout mutation AND a successful refetch .

With the current implementation, onCompleted will never be called because as soon as refetchQueries is finished, the logout mutation will unmount and the redirect will never happen.

{loggedIn && ( // ← mutation rendering is conditional 
  <Mutation
    awaitRefetchQueries
    mutation={logoutMutation}
    refetchQueries={[/* a query to update the current user info (e.g. loggedIn) */]}
    onCompleted={redirectToLogin /* this callback will never be called */}
  >
    {/* a logout button to run the mutation when clicked */}
  </Mutation>
)}

This might not be the best example, but hopefully it can demonstrate the real issue the PR is trying to address.

Replicating the Issue

I was able to replicate this issue easily when I tried to pass an onCompleted callback to the Mutation in this test and assert that it was called:

The Cause

It appears that this is intentional in order to avoid updating the Mutation internal state after it un-mounts.

private onMutationCompleted = (response: ExecutionResult<TData>, mutationId: number) => {
if (this.hasMounted === false) {
return;
}

Unless I'm missing something here or there is a reason not do so, this doesn't necessarily mean that an onCompleted callback should never be called when a mutation is resolved and has been unmounted.

While it can be hard to think that an unmounted component would have callbacks called, it is important to keep in mind that consumers of an unmounted Mutation have no indication to when the said mutation is resolved successfully or when its refetched queries are finished (same for errors).

Possible Fix

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.

I also went ahead and applied the same changes to onError/onMutationError for consistency.

@wsmd wsmd requested review from benjamn and hwillson as code owners January 6, 2019 23:53
@apollo-cla
Copy link

@wsmd: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Meteor Contributor Agreement here: https://contribute.meteor.com/

@wsmd wsmd changed the title [WIP] invoke onCompleted/onError after Mutiation unmounts Invoke onCompleted/onError after Mutiation unmounts Jan 7, 2019
@wsmd wsmd changed the title Invoke onCompleted/onError after Mutiation unmounts Invoke onCompleted/onError even if Mutiation unmounts Jan 7, 2019
Copy link
Contributor

@rosskevin rosskevin left a comment

Choose a reason for hiding this comment

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

I think this change looks good and does not violate current assertions. Would prefer a separate test grouped with the current under something like describe('after unmounting', => so that we have an easier time understanding the test area.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants