-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
useQuery silently returns null data when cache is missing some field #6375
Comments
I'm wondering if this is related to an issue I am seeing where if I have two queries that request different fields I get a MissingFieldError because the first one gets cached and the second one then can't use the result in the cache because it is incomplete |
I get const MIXED_QUERY = gql`
query {
remoteField
localField @client
}
`
const { loading, data, error } = useQuery(MIXED_QUERY)
console.log(loading, data, error) Current behavior
Desired behavior
Versions @apollo/client 3.2 |
Hi @fromi and others in this thread! Thanks for your patience on this. I'm doing some housekeeping and would be eager to learn whether this is still an issue in a more recent version of the client. If so, does anyone have a reproduction available via a codesandbox or sample repo? Thanks much! |
Hi @bignimbus! Sorry, I do not have time nowadays to try to reproduce the issue :/ |
I was facing the same problem, it was caching the ALL_MATCHES query but it was not caching ALL_GROUPS, I was hitting two different queries with the same variables, like: const { loading: groupsLoading, data: groupsTableData } = useQuery(ALL_GROUPS, {
variables: {
filter: {
tournament: 1,
...(selectedSegment ? { segment: selectedSegment } : {}),
...(selectedCategory ? { tournamentCategory: selectedCategory } : {}),
},
}
});
const { loading: matchesLoading, data: matchesTableData } = useQuery(ALL_MATCHES, {
variables: {
filter: {
tournament: 1,
...(selectedSegment ? { segment: selectedSegment } : {}),
...(selectedCategory ? { tournamentCategory: selectedCategory } : {}),
},
},
}); And then i added 1 extra variable "queryName" for uniquely saving in the cache because i think Apollo client cache queries based on unique variable fields. const { loading: groupsLoading, data: groupsTableData } = useQuery(ALL_GROUPS, {
variables: {
filter: {
tournament: tournamentId,
...(selectedSegment ? { segment: selectedSegment } : {}),
...(selectedCategory ? { tournamentCategory: selectedCategory } : {}),
},
queryName: "allGroups",
}
});
const { loading: matchesLoading, data: matchesTableData } = useQuery(ALL_MATCHES, {
variables: {
filter: {
tournament: tournamentId,
...(selectedSegment ? { segment: selectedSegment } : {}),
...(selectedCategory ? { tournamentCategory: selectedCategory } : {}),
},
queryName: "allGroupMatches",
},
});
const [updateGroup] = useMutation(UPDATE_GROUP, {
update(cache, { data: { updateGroup } }) {
const {allGroups}: any = cache.readQuery({
query: ALL_GROUPS,
variables:{
filter:{
tournament: auth.tournamentId,
...(selectedCategory ? { tournamentCategory: selectedCategory } : {}),
...(selectedSegment ? { segment: selectedSegment } : {}),
},
queryName: "allGroups",
}
});
cache.writeQuery({
query: ALL_GROUPS,
variables:{
filter:{
tournament: auth.tournamentId,
...(selectedCategory ? { tournamentCategory: selectedCategory } : {}),
...(selectedSegment ? { segment: selectedSegment } : {}),
},
queryName: "allGroups",
},
data: {
// updated data
},
});
},
}); |
Intended outcome:
I have a local field named "displayedGame":
It references a Game in the cache:
ROOT_QUERY: displayedGame: {__ref: "Game:6k3ZEe3AouGr"}
I receive a real time notification (not using Subscription because I use a Serverless + Pusher architecture). This notification informs that a player joined the game.
I use
client.writeFragment({id: 'Game:' + gameId, fragment: GAME_PLAYERS, data: {players}})
in order to update the list of players in the cache.Actual outcome:
When I do that, useQuery starts returning null data AND null error:
const {data, error} = useQuery<{ displayedGame: Game }>(GET_DISPLAYED_GAME)
After investigating a lot, it appears that the data is null because the field "player.name" of the new player is undefined in the cache: it is not in my real time notification because it is indeed undefined in my database, but the cache expects it to be null.
I only managed to understand that because I tried to run
client.readQuery<{ displayedGame: Game }>({query: GET_DISPLAYED_GAME})
directly on the cache: doing that I had a clear error:MissingFieldError: Can't find field 'name' on object {__typename: Player, id: ...}
Expected behavior
How to reproduce the issue:
Use
writeFragment
to inject partial data in the cache for a client side directive field, and watchuseQuery
silently return null data with no error.Versions
@apollo/client 3.0.0-beta.50
The text was updated successfully, but these errors were encountered: