Skip to content
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

Potential issue caching an object by _id field #19

Closed
sbrichardson opened this issue Dec 22, 2017 · 1 comment
Closed

Potential issue caching an object by _id field #19

sbrichardson opened this issue Dec 22, 2017 · 1 comment
Labels

Comments

@sbrichardson
Copy link

sbrichardson commented Dec 22, 2017

I ran into this edge case when working on a dynamic component builder, this is just a rough preview of it's functionality. As you select fields that you would like on the component, the GraphQL query and resulting data from the database update to reflect your selections.

I noticed when selecting the ID (_id) field when the item is already cached without the _id field selected, the cache breaks and throws errors for that particular item. It seems like the cache will store an item differently if the actual data has the _id property within the selection set.

I could see this causing an issue for normal users if two queries use the same _id variable, but on one route includes the _id property in the selection set, and a query on another route doesn't. I'm probably going to use a custom cache persister, but wanted to let you know about this anyway.

Here is a YouTube video link for clarity. The issue is visible about 20 secs in, when the _id field is added in.

screen shot 2017-12-21 at 6 44 23 pm

Here's a link to part of the source code. Apologies, but can't release a full working version

Here is a copy of the error:

Store error: the application attempted to write an object with no provided id but the store already contains an id of BackupMonitor:5a3c5721ae08b284c4de251b for this object. The selectionSet that was trying to be written is:
BackupMonitor(_id: "5a3c5721ae08b284c4de251b") {
  PlanName
  CompanyName
  UserName
  UserID
  tenant_id
  __typename
} could not be cloned.
    at ApolloClient.hookLogger [as devToolsHookCb] (<anonymous>:14:14)
    at QueryManager.onBroadcast (http://localhost:3000/static/js/bundle.js:2526:27)
    at QueryManager../node_modules/apollo-client/core/QueryManager.js.QueryManager.broadcastQueries (http://localhost:3000/static/js/bundle.js:3612:14)
    at Object.next (http://localhost:3000/static/js/bundle.js:3652:31)
    at SubscriptionObserver.next (http://localhost:3000/static/js/bundle.js:117881:14)
    at http://localhost:3000/static/js/bundle.js:5682:76
    at Array.forEach (<anonymous>)
    at Object.next (http://localhost:3000/static/js/bundle.js:5682:43)
    at SubscriptionObserver.next (http://localhost:3000/static/js/bundle.js:117881:14)
    at Object.next (http://localhost:3000/static/js/bundle.js:6987:34)
    at SubscriptionObserver.next (http://localhost:3000/static/js/bundle.js:117881:14)
    at http://localhost:3000/static/js/bundle.js:8558:81
    at retry (http://localhost:3000/static/js/bundle.js:8554:17)
    at Object.next (http://localhost:3000/static/js/bundle.js:8558:21)
    at SubscriptionObserver.next (http://localhost:3000/static/js/bundle.js:117881:14)
    at http://localhost:3000/static/js/bundle.js:8406:26
    at <anonymous>
VM48:17 DOMException: Failed to execute 'postMessage' on 'Window': Error: Error writing result to store for query:
 {
  BackupMonitor(_id: "5a3c5721ae08b284c4de251b") {
    PlanName
    CompanyName
    UserName
    UserID
    tenant_id
    __typename
  }
}
@jamesreggio
Copy link
Contributor

Hi @sbr464 — this is actually a concern with apollo-cache-inmemory and is unrelated to apollo-cache-persist.

apollo-cache-inmemory has special behavior around the id and _id fields, as described in the Normalization section of its README. Because the InMemoryCache uses these fields to normalize objects, they're required to be stable (i.e., not change, and not appear/disappear between queries and writes).

As a rule of thumb, you should always include id or _id (whichever you're using as the globally-unique ID field) on every query and mutation that impacts an object. This will side-step the errors you're seeing, and can result in better cachability (since Apollo will otherwise generate a position-dependent ID for the object, which is much less reusable).

Hope this helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants