react-apollo
react-apollo copied to clipboard
useLazyQuery: cannot read property 'subscribeToMore' of undefined when attempting to resubscribe
Intended outcome: Attempting to useLazyQuery & subscribeToMore with a changing variable to the query. NOTE - if I change this to useQuery it works as expected. I was trying to avoid the execution of the graphql query when the identifier is undefined (on initial component load)
Actual outcome:
Cannot read property 'subscribeToMore' of undefined at QueryData._this.obsSubscribeToMore (QueryData.ts:476)
How to reproduce the issue: I have an input in Header component where you can enter the identifier which is written to apollo-cache. On initial PeopleContainer mount, the identifier is undefined. Then enter an identifier in the Header & hit Enter the LazyQuery & subscriptions execute correctly. Change the identifier & hit Enter again it throws the error above.
const PeopleContainer = () => {
//get from ApolloCache
const {
data: {
people: { identifier },
},
} = useQuery(GET_IDENTIFIER);
const [getPeople, { loading, data, error, subscribeToMore }] = useLazyQuery(GET_PEOPLE);
useEffect(() => {
if (identifier) {
getPeople({ variables: { identifier } });
}
}, [identifier]);
useEffect(() => {
if (identifier && subscribeToMore) {
const updateUnsubcribe = 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 () => {
updateUnsubcribe();
deleteUnsubscribe();
};
}
}, [identifier, subscribeToMore]);
Version
System:
OS: macOS Mojave 10.14.6
Binaries:
Node: 12.13.1 - /usr/local/bin/node
Yarn: 1.22.0 - /usr/local/bin/yarn
npm: 6.12.1 - /usr/local/bin/npm
Browsers:
Chrome: 80.0.3987.122
Safari: 13.0.5
npmPackages:
@apollo/react-hooks: ^3.1.3 => 3.1.3
apollo-cache-inmemory: ^1.6.5 => 1.6.5
apollo-client: 2.6.8 => 2.6.8
apollo-link: ^1.2.13 => 1.2.13
apollo-link-ws: ^1.0.19 => 1.0.19
I got the same error
System: OS: macOS Mojave 10.15.3 Binaries: Node: v13.0.1 - ~/.nvm/versions/node/v13.0.1/bin/node npm: 6.12.0 - ~/.nvm/versions/node/v13.0.1/bin/npm Browsers: Chrome: 80.0.3987.122 Safari: 13.0.5 npmPackages: "@apollo/react-hooks": "^3.1.3", "apollo-boost": "^0.1.28", "apollo-client": "^2.6.4", "apollo-link-context": "^1.0.9", "apollo-link-retry": "^2.2.10", "react-apollo": "^3.1.1",
I got same issue. But found a workaround. I'm not sure if it is correct, but I got working it in this way (code is taken from first post):
const PeopleContainer = () => {
//get from ApolloCache
const {
data: {
people: { identifier },
},
} = useQuery(GET_IDENTIFIER);
const [getPeople, { called, refetch, loading, data, error, subscribeToMore }] = useLazyQuery(GET_PEOPLE);
useEffect(() => {
if (identifier && !called) {
getPeople({ variables: { identifier } });
}
}, [getPeople, identifier, called]);
useEffect(() => {
if (identifier && called) {
refetch({ identifier });
}
}, [refetch, identifier, called]);
useEffect(() => {
if (identifier && subscribeToMore) {
const updateUnsubcribe = 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 () => {
updateUnsubcribe();
deleteUnsubscribe();
};
}
}, [identifier, subscribeToMore]);
I've encountered the same problem. I miss some examples on how to correctly combine useLazyQuery
and subscribeToMore
with variables validation (undefined
)...
Confirmed @ViktorsOvcinnikovs workaround. Any idea if this will get fixed in ApolloClient 3.0?
With @ViktorsOvcinnikovs workaround the query and a refetch both are called on the first render. Not ideal but so far the only way to make this work. I wonder if this is not supported and we should run useSubscription instead and update the cache with the results.