apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.37k stars 2.66k forks source link

useLazyQuery: cannot read property 'subscribeToMore' of undefined when attempting to resubscribe #7543

Open mstykow opened 3 years ago

mstykow commented 3 years ago

NOTE: RE-OPENING A REACT-APOLLO ISSUE WHICH STILL OCCURS ON APOLLO-CLIENT. See: https://github.com/apollographql/react-apollo/issues/3860

Intended outcome: Attempting to use useLazyQuery and subscribeToMore with a potentially undefined variable should not lead to crashes. The intention here is only execute the GraphQL query when the identifier becomes defined.

Actual outcome: Cannot read property 'subscribeToMore' of undefined at QueryData._this.obsSubscribeToMore (QueryData.ts:476).

Potential fix: If you check the code in QueryData.ts, you will see that Apollo Client uses non-null assertion for something that can actually be null. Perhaps simply using optional chaining instead could fix the issue.

How to reproduce the issue:

const [getPeople, { loading, data, error, subscribeToMore }] = useLazyQuery(GET_PEOPLE);

useEffect(() => {
    if (identifier) {
      getPeople({ variables: { identifier } });
    }
}, [identifier]);

useEffect(() => {
    if (identifier && subscribeToMore) {
      const updateUnsubscribe = subscribeToMore({
        document: UPDATE_PEOPLE
        variables: { identifier },
        updateQuery: (prev, { subscriptionData }) => handleUpdate(prev, subscriptionData),
      });

      const deleteUnsubscribe = subscribeToMore({
        document: DELETE_PEOPLE,
        variables: { identifier },
        updateQuery: (prev, { subscriptionData }) => handleDelete(prev, subscriptionData),
      });

      return () => {
        updateUnsubscribe();
        deleteUnsubscribe();
      };
    }
  }, [identifier, subscribeToMore]);

Versions

System:
    OS: Linux 5.4 Ubuntu 20.04.1 LTS (Focal Fossa)
  Binaries:
    Node: 12.13.1 - ~/.nvm/versions/node/v12.13.1/bin/node
    Yarn: 1.22.5 - ~/.yarn/bin/yarn
    npm: 6.12.1 - ~/.nvm/versions/node/v12.13.1/bin/npm
  Browsers:
    Chrome: 87.0.4280.88
    Firefox: 84.0
  npmPackages:
    @apollo/client: ^3.2.7 => 3.3.6 
    apollo-link-http: ^1.5.17 => 1.5.17

Known Workaround

const [getPeople, { loading, refetch, data, error, subscribeToMore }] = useLazyQuery(GET_PEOPLE);

useEffect(() => {
    if (identifier) {
      refetch ? refetch({ identifier }) : getPeople({ variables: { identifier } });
    }
}, [identifier, refetch]);
AdityaPratap006 commented 3 years ago

@mstykow Thanks a lot man!! This is definitely a bug, however thanks to your workaround I was able to solve my problem for now. Hope they fix this as soon as possible.