Apollo-client: update fails if a query has not yet been executed

Created on 7 Aug 2017  路  14Comments  路  Source: apollographql/apollo-client

Not sure if this is a bug or intended behaviour, however, it doesn't work for my use case. The same thing has been reported (and fixed) for refetchQueries (see #690), although I do realise that this case is different.

Intended outcome:
I'm executing a mutation query which afterwards requires a manual update of the store. However, I cannot guarantee that the query I want to update has been run with the exact parameters already. If the query has not yet been executed I don't care about the update, since the result must be fetched from the server anyway.

(A simple example to illustrate the issue: consider a simple to do app. The user can view pending tasks and completed tasks. Also, the user can mark a pending task as done. The main view only shows (and queries for) pending tasks, since always loading the large number of completed tasks would impact performace. If the user marks a pending task as done, the query for completed tasks should be updated, but may not have been executed before.)

Actual outcome:
I'm using update to manually update the store. If the query I want to update has not yet been run, proxy.readQuery() will throw an error.
For my use case it would be better to return null, so that I can decide myself what to do in this case (which would be to just do nothing). I realise I could achieve this with try/catch, but this feels wrong.

How to reproduce the issue:
Execute a mutation query with an update method, which tries to read a query from the store that has not yet been executed (using the DataProxy's readQuery() method).

Version

Most helpful comment

Also, it feels wrong to manage control flow through try/catch in this way -- a query that hasn't been executed yet is not necessarily an exception, it may well be a valid use case.
An alternative would be to offer a method returning a boolean indicating whether the query has already been executed that could then be used with an if block.

All 14 comments

This issue has been automatically marked as stale becuase it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client!

The issue still exists -- see also #2024

I'm running into the same exact use case and having proxy.readQuery() return null would make a lot of sense.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client!

hmm, I'm not sure about this. null would likely denote that the query had no data (such as when an errors array is returned) versus not existing yet which currently throws.

I'd love to hear some thoughts on this and will add this to the post 2.0 milestone to at least improve the docs on this, or actually make a change

There could still be a clear distinction between null and {"data": []}, with the latter indicating no data (optionally with an errors property, just like a real query), the former indicating that the query has not yet been executed.

I agree that something needs to be done here. The example code in the docs at http://dev.apollodata.com/react/cache-updates.html is problematic because it does not catch the error in the case when the updated query has not yet been executed. We would need to add a catch clause to every such update which results in too much boilerplate for writing update code.

Also, it feels wrong to manage control flow through try/catch in this way -- a query that hasn't been executed yet is not necessarily an exception, it may well be a valid use case.
An alternative would be to offer a method returning a boolean indicating whether the query has already been executed that could then be used with an if block.

Yea, i would like some solution too, because try/catch its not ideal at all if you use some-kind of logs for errors (sentry etc.).

Hello, any updates here? Are you accepting PR on that? What is the desired solution? Return null?

Looks like a simple change here will fix the problem
https://github.com/apollographql/apollo-client/blob/3cc19679ae0d12234f2ec36cb9d3b2d6180d2f7f/packages/apollo-cache-inmemory/src/inMemoryCache.ts#L76

This condition is inside read
https://github.com/apollographql/apollo-client/blob/3cc19679ae0d12234f2ec36cb9d3b2d6180d2f7f/packages/apollo-cache-inmemory/src/inMemoryCache.ts#L75-L89

cc @jbaxleyiii

The same problem exists in "apollo-client": "2.0.4"

The only decent workaround I found is using apollo-link-state and predefining defaults for the said query otherwise it just throws which is not ideal.

any updates on this?

any update ?

Same happening with apollo-client: 2.3.0 ?
It is really annoying having to catch and parse the error message, just to make sure we are not catching any other error :(

Here is the error that I'm getting. I'm manually calling client.readQuery({ ... }).

readFromStore.js:42 Uncaught (in promise) Error: Can't find field changeSets({"project":"wd301"}) on object (ROOT_QUERY) {
  "myProjects": []
}.
    at readStoreResolver (readFromStore.js:42)
    at executeField (graphql.js:70)
    at graphql.js:27
    at Array.forEach (<anonymous>)
    at executeSelectionSet (graphql.js:22)
    at Object.graphql [as default] (graphql.js:17)
    at diffQueryAgainstStore (readFromStore.js:74)
    at Object.readQueryFromStore (readFromStore.js:16)
    at InMemoryCache.read (inMemoryCache.js:75)
    at InMemoryCache.readQuery (inMemoryCache.js:170)
    at ApolloClient.readQuery (ApolloClient.js:179)

To help provide a more clear separation between feature requests / discussions and bugs, and to help clean up the feature request / discussion backlog, Apollo Client feature requests / discussions are now being managed under the https://github.com/apollographql/apollo-feature-requests repository.

Migrated to: https://github.com/apollographql/apollo-feature-requests/issues/1

Was this page helpful?
0 / 5 - 0 ratings