I have two simple queries:
query GerMenuA {
menus {
menuA {
items {
label
}
}
}
}
query GerMenuB {
menus {
menuB {
items {
label
}
}
}
}
But in the console I see a warning:
Cache data may be lost when replacing the menus field of a Query object.
existing: {"__typename":"Menu","menuA":[{...}]}
incoming: {"__typename":"Menu","menuB":[{...}]}
Is there a way just do not merge them and remove the warning? Because if specify in typePolicies
Menu: { merge: true }
or
Menu: { merge: false }
it is not what I want, because these are different data and these two queues do not need to be merged in any way. Also, I don't have an id
field and keyFields
will not work for this case, because labels could be the same for both menus
So your question is hard to answer without your schema typedefs. But let's suppose it's something like this:
type Query {
menus: Menus
}
type Menus {
menuA: Menu
menuB: Menu
}
The warning is essentially saying that without any keyArgs
Apollo Cache has no way to normalize the menus
Query. Keep in mind from their standpoint- you have a single menus
root query. (i.e. GerMenuA
and GerMenuB
are client side queries not root queries).
(Side note- since you don't have id
fields see disabling normalization.)
Option 1: Separate Your Queries
type Query {
menuA: Menu
menuB: Menu
}
Apollo cache will now store menuA
and menuB
as separate queries. If you want to be safe you can set your type policies:
const createCache = () => new InMemoryCache({
typePolicies: {
Menu: {
keyFields: false
},
Query: {
fields: {
menuA: {
keyArgs: false
},
menuB: {
keyArgs: false
}
}
}
},
});
keyFields: false
tells AC to store Menu
under it's parent query. keyArgs: false
says that both menuA
and menuB
are singleton queries. Cache policy will default to merge: false
so that existing data will be replaced by incoming.
Option 2: Define Query Parameter
In this option, you add a name
parameter to your menus
query:
type Query {
menus(name: String): Menu
}
By default, the cache stores a separate value for every unique combination of argument values you provide when querying a particular field.
Apollo cache will now store menus:{name:menuA}
and menus:{name:menuB}
as separate cache objects. Again, if you want to be safe you can set your type policies:
const createCache = () => new InMemoryCache({
typePolicies: {
Menu: {
keyFields: false
}
},
});
Again, the cache policy will default to merge: false
so that existing data will be replaced by incoming.
Option 3: Define Merge Policy
We've covered why the existing schema is confusing to Apollo Cache. But if you're really set on it, the remaining thing to do is define a merge policy:
const createCache = () => new InMemoryCache({
typePolicies: {
Menu: {
keyFields: false
},
Menus: {
keyFields: false,
merge: true
},
Query: {
fields: {
menus: {
keyArgs: false,
merge: true
}
}
}
},
});
merge: true
tells Apollo Cache to merge the results of GerMenuA
and GerMenuB
into a single Menus
cache object with both menuA
and menuB
properties. Without it each time you ran a query you'd blow away the results of the previous query.