apollo-client: cache.readQuery with variables doesn't work

I have the following code and don’t work, I’m struggling to make it work for the last 4 days.

const newTodo = {
   id: 0,
   text: "text",
   completed: false,
   __typename: "todo"
 };

 const data = {
   todos: [newTodo]
 };

 cache.writeData({ data });

 const GET_TODOS = gql`
   query todo($id: Int!) {
     todos(id: $id) {
       id
       completed
       text
     }
   }
 `;

 const da = cache.readQuery({ query: GET_TODOS, variables: { id: 0 } });

I get the error message:

Uncaught Invariant Violation: Can't find field todos({"id":0}) on object {
  "todos": [
    {
      "type": "id",
      "generated": false,
      "id": "todo:0",
      "typename": "todo"
    }
  ]
}.
    at new InvariantError

please advice what i’m doing wrong…

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 3
  • Comments: 24 (8 by maintainers)

Most upvoted comments

From the Apollo docs readQuery section:

If your cache doesn’t contain all of the data necessary to fulfill a specified query, readQuery throws an error. It never attempts to fetch data from a remote server.

I kept running into this when using readQuery to grab an item from the Apollo cache when said item wasn’t cached yet. If you’re getting the invariant violation error and your query is formatted properly (e.g. all the necessary variables are set), check to make sure the item(s) for which you’re querying are, in fact, already in the cache.

In the cases where I suspect the item(s) may not yet be in the cache, and I’m using readQuery to get them, I wrap the block in a try / catch.

Calling client.query instead works fine, this is maybe a misunderstanding of readQuery that I naively thought will check if exists in cache and if not will call client.query… (otherwise I don’t get the difference between client.readQuery and cache.readQuery).

I also suggest, the update method of a mutation provide client as a param since I always need to pass it using the withApollo() artefact generating unnecessary boilerplate code