apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.38k stars 2.66k forks source link

Ghost data when reading from cache. `readQuery` doesn't work as expected? #3859

Closed matiasfha closed 5 years ago

matiasfha commented 6 years ago

Intended outcome: The queries should be fulfilled with the requested data that is in the cache.

Actual outcome: Some queries fails to return the data from the cache with a missing data error

The use case is the follow: I'm working in offline support for an app that is currently using apollo + react. To accomplish these we decide to use the cache features of apollo along with apollo-cache-persist to save the cache store. That part of the setup works good. Now, in order to allow the app to get the data while offline I added a link, that catch the queries that are made and, if the app is offline then return the response reading from the cache to avoid hitting the network (the idea here is to add the offline support as a drop-in). To enable this, the app have a "Download data" button that perform lot of queries to retrieve the whole set of data required for offline use. All of these data then is present in the Apollo cache. Then the app goes offline and whenever a query is triggered, the link catch that and return the data that is in the cache, performing the same query but with client. readQuery. Here is where the issue arise. For some reason, there are certain data that is not found when client.readQuery is fired up. But the data is available in the cache according the devtools. Also to be sure that the data was available. I added a client.readQuery and client.readFragment tests after the data is fetched and the data is there. The output of the issue (the client.readQuery is inside a try/catch block) is:


  "rules": {
    "type": "id",
    "generated": true,
    "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).rules",
    "typename": "QbankRules"
  },
  "quiz": [
    {
      "type": "id",
      "generated": false,
      "id": "Test-78808578",
      "typename": "Test"
    },
    {
      "type": "id",
      "generated": false,
      "id": "Test-78715876",
      "typename": "Test"
    },
    {
      "type": "id",
      "generated": false,
      "id": "Test-78715779",
      "typename": "Test"
    },
    {
      "type": "id",
      "generated": false,
      "id": "Test-77905135",
      "typename": "Test"
    },
    {
      "type": "id",
      "generated": false,
      "id": "Test-77494402",
      "typename": "Test"
    }
  ],
  "__typename": "Qbank",
  "customInstructions": "<p><span style=\"font-weight: 400;\">Create a fixed-length quiz based on any section of the curriculum and select the quiz difficulty.</span></p>",
  "adaptiveInstructions": "<p><span style=\"font-weight: 400;\">Create a topic-level quiz that is matched to your current ability. As topic proficiency increases, the questions become more difficult.</span></p>",
  "stats": {
    "type": "id",
    "generated": true,
    "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).stats",
    "typename": "QbankStats"
  },
  "nodes({})": [
    {
      "type": "id",
      "generated": true,
      "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).nodes({}).0",
      "typename": "Node"
    },
    {
      "type": "id",
      "generated": true,
      "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).nodes({}).1",
      "typename": "Node"
    },
    {
      "type": "id",
      "generated": true,
      "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).nodes({}).2",
      "typename": "Node"
    },
    {
      "type": "id",
      "generated": true,
      "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).nodes({}).3",
      "typename": "Node"
    },
    {
      "type": "id",
      "generated": true,
      "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).nodes({}).4",
      "typename": "Node"
    },
    {
      "type": "id",
      "generated": true,
      "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).nodes({}).5",
      "typename": "Node"
    },
    {
      "type": "id",
      "generated": true,
      "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).nodes({}).6",
      "typename": "Node"
    },
    {
      "type": "id",
      "generated": true,
      "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).nodes({}).7",
      "typename": "Node"
    },
    {
      "type": "id",
      "generated": true,
      "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).nodes({}).8",
      "typename": "Node"
    },
    {
      "type": "id",
      "generated": true,
      "id": "$ROOT_QUERY.person.learner.qbank({\"enrollmentDetailId\":\"21200114\"}).nodes({}).9",
      "typename": "Node"
    }
  ],
  "quiz({\"testId\":78715876})": [
    {
      "type": "id",
      "generated": false,
      "id": "Test-78715876",
      "typename": "Test"
    }
  ],
...
...```
But the test object identified by `78715876` is there!..
The query is the same query that works while online and the same query that was triggered by the download data button.
Any idea about why the data is not found even if was cached?
Just mention that the app is using the `dataIdFromObject`  to configure the `InMemoryCache`
where the `Test` id is mapped to `Test-${testId}`
<!--
If possible, please create a reproduction using https://github.com/apollographql/react-apollo-error-template and link to it here. If you prefer an in-browser way to create reproduction, try https://codesandbox.io/s/7361K9q6w

Instructions for how the issue can be reproduced by a maintainer or contributor. Be as specific as possible, and only mention what is necessary to reproduce the bug. If possible, try to isolate the exact circumstances in which the bug occurs and avoid speculation over what the cause might be.
-->

**Versions**
<!--
Run the following command in your project directory, and paste its (automatically copied to clipboard) results here:

`npx envinfo@latest --preset apollo --clipboard`
-->

  System:
    OS: macOS 10.14
  Binaries:
    Node: 9.3.0 - ~/.nvm/versions/node/v9.3.0/bin/node
    Yarn: 1.9.4 - /usr/local/bin/yarn
    npm: 5.6.0 - ~/.nvm/versions/node/v9.3.0/bin/npm
  Browsers:
    Chrome: 67.0.3396.87
    Firefox: 58.0.2
    Safari: 12.0
hwillson commented 6 years ago

This definitely seems strange @matiasfh - any chance you can provide a small runnable reproduction that shows this happening?

mregula commented 5 years ago

I have the same problem. It turned out that I forgot to include subfields in my client query.

danilobuerger commented 5 years ago

Closing as no reproduction was provided in one week. Feel free to reopen if you have a minimal reproduction.