-
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
Calling readQuery when query may or may not be in cache #4309
Comments
I think you want to follow the existing feature request related to this shortcoming of Apollo client. |
You could also consider defining a default state via apollo-link-state |
Issues here are reserved for bugs, but one of the following resources should help:
|
@danielstreit Have you found a more elegant solution than manual checking if that key exists in the cache? I have the same issue. |
I did not. The best I could do was wrap the manual check in a util function so if/when it ever breaks, I only have to fix it in one place. |
Yeah, I am going to do something similar. I wish there was a better solution. Maybe this will be sorted in Apollo Client 3. |
I ended up just wrapping the cache read in try/catch block so at minimum doesn't blow up on me. That way when you go from a page such as Note the downside of the below mutation is if you have paged list that has any sort of filters, or sorting it will probably break so you may end up just wanting to always re-hydrate your cache after the update anyway. const isNew = true; // defined elsewhere
const [createOrUpdate] = useMutation(upsertUser, {
update: (cache, { data: { upsertUser} }) => {
if (isNew) {
// if this is a new user we need to append to our users list
try {
// read users list from cache
const data = cache.readQuery({
query: usersQuery,
});
// Push new user on to the list
cache.writeQuery({
query: usersQuery,
data: {
users: [upsertUser, ...data.users],
},
});
} catch (_) {
// Cache isn't populated yet
}
} else {
// User exists so just update the fragment
cache.writeFragment({
id: user.id,
fragment: UserFragment,
data: upsertUser,
});
}
// After update go back to the whole list of users page
// react-router
history.push('/users');
},
}); Not really sure the best solution that fits everyone's use case but I am open to suggestions and would be more than happy to submit PR. |
I have a mutation that needs to update a query that may or may not have been run. If I simply call readQuery on the cache, and the query has not already run, I get an error
Error: Can't find field allDashboards on object undefined.
(with some variation depending upon whether there are any queries in the cache at all).I found a workaround, by checking if the query exists in the cache before attempting to read it:
if (has(cache, ['data', 'data', 'ROOT_QUERY', 'allDashboards']))
. This seems brittle to me...it depends on implementation details of the cache.Is there a better way to do this? I don't see a
hasQuery
method on the cache, which seems like it would solve this issue, but maybe there is a reason for that method not to exist?Another approach could be to throw an error of a known type (rather than a generic JavaScript error), so I could catch a cache miss error but not swallow every error that might happen.
Any suggestions or help would be appreciated! Thanks!
The text was updated successfully, but these errors were encountered: