Apollo readQuery Fails Even Though Target Object i

2019-06-07 00:00发布

问题:

I'm working on a call to readQuery. I'm getting an error message:

modules.js?hash=2d0033b4773d9cb6f118946043f7a3d4385825fe:25847 
Error: Can't find field resolutions({"id":"Resolution:DHSzPa8bvPCDjuAac"}) 
on object (ROOT_QUERY) {
  "resolutions": [
    {
      "type": "id",
      "id": "Resolution:AepgCCio9KWGkwyMC",
      "generated": false
    },
    {
      "type": "id",
      "id": "Resolution:DHSzPa8bvPCDjuAac",  // <==ID I'M SEEKING
      "generated": false
    }
  ],
  "user": {
    "type": "id",
    "id": "User:WWv57KsvqWeAoBNHY",
    "generated": false
  }
}.

The object with that id appears to be plainly visible as the second entry in the list of resolutions.

Here's my query:

const GET_CURRENT_RESOLUTION_AND_GOALS = gql`
  query Resolutions($id: String!) {
    resolutions(id: $id) {
      _id
      name
      completed
      goals {
        _id
        name
        completed
      }
    }
  }
`;

...and here's how I'm calling it:

<Mutation
    mutation={CREATE_GOAL}
    update={(cache, {data: {createGoal}}) => {
        let id = 'Resolution:' + resolutionId;
        const {resolutions} = cache.readQuery({
            query: GET_CURRENT_RESOLUTION_AND_GOALS,
            variables: {
                id
            },
        });
    }}
>

What am I missing?

Update

Per the GraphQL Dev Tools extension for Chrome, here's the whole GraphQL data store:

{
  "data": {
    "resolutions": [
      {
        "_id": "AepgCCio9KWGkwyMC",
        "name": "testing 123",
        "completed": false,
        "goals": [
          {
            "_id": "TXq4nvukpLcqQhMRL",
            "name": "test goal abc",
            "completed": false,
            "__typename": "Goal"
          },
        ],
        "__typename": "Resolution"
      },
      {
        "_id": "DHSzPa8bvPCDjuAac",
        "name": "testing 345",
        "completed": false,
        "goals": [
          {
            "_id": "PEkg5oEEi2tJ6i8LH",
            "name": "goal abc",
            "completed": false,
            "__typename": "Goal"
          },
          {
            "_id": "X4H4dFzGm5gkq5bPE",
            "name": "goal bcd",
            "completed": false,
            "__typename": "Goal"
          },
          {
            "_id": "hYunrXsMq7Gme7Xck",
            "name": "goal cde",
            "completed": false,
            "__typename": "Goal"
          }
        "__typename": "Resolution"
      }
    ],
    "user": {
      "_id": "WWv57KsvqWeAoBNHY",
      "__typename": "User"
    }
  }
}

回答1:

Posted as answer for fellow apollo users with similar problems:

Remove the prefix of Resolution:, the query should only take the id.

Then the question arises how is your datastore filled? To read a query from cache, the query needs to have been called with exactly the same arguments on the remote API before. This way apollo knows what the result for a field is with specific arguments. If you never called the remote endpoint with the arguments you want to use but know what the result would be, you can circumvent that and resolve the query locally by implementing a cache resolver. Have a look at the example in the documentation. Here the store contains a list of books (in your case resultions) and the query for a single book by id can be resolved with a simple cache lookup.