-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Issues with @client
normalization, optimisticResponse, and field policies
#7941
Comments
@wallzero Sorry for the complexity/frustration, but thank you for your patience in providing this level of detail. A few ideas:
|
@benjamn Thanks for getting back so quickly! With the holiday weekend approaching, I may not follow up until Monday/Tuesday - but here's a few notes.
NodsicGraphSettings: {
keyFields: ['graphId']
} So after reflecting for a bit I think it's easier to distill this into two complementing issues:
query GraphPreload (
$graphId: ID!
) {
graph (
graphId: $graphId
) {
graphId
name
settings @client {
graphId
zoom
x
y
}
}
} ...the
I should be able to whip up a reproduction in a few days. Thanks again! |
@benjamn Here is an early reproduction: https://github.com/wallzero/react-apollo-error-template I was able to demonstrate the first issue; The second issue is actually working in the reproduction - |
I'm pretty sure what is happening is |
Same Issue |
any advance? |
Intended outcome:
I am trying to tack on a local field to an otherwise normal query and expect the local field to be normalized and the cache to create a ref. I have a read field resolver providing a default value.
Actual outcome:
The default value provided by the read field resolver is not normalized. Inspecting the parent, it contains no reference to any normalized object returned by the read field policy. This means that while the query for the
@client
field was returned, it is unable to update the field viacache.modify
to persist any changes.How to reproduce the issue:
Basically I am querying a graph-like object. I also will need a local
@client
Original schema:
Extended schema to accommodate local settings:
My field policy:
I then query the graph:
And I can see my field policy is working and on first read it will return the defaults.
At some point, I want to mutate the
GraphSettings
:Then I return a simple optimistic response from my
mutate()
:This is where things become interesting. First, I tried creating a
merge
function in my field policy for thegraphSettingsUpdate
mutation:This merge function is called but
existingSettings
is empty.newSettings
returns a ref instead of a settings object, andreadField
can read updated values from that ref.So I tried to
readField
the fields from theref
andcache.modify
to update the settings but as I said aboveGraph
does not have asettings
reference in the cache andcache.modify
will not create a new field. What is also strange is I can't find aGraphSettings
object normalized in the cache either (not sure howreadField
is working then...)So instead I tried
cache.writeFragment
to "force" a normalized reference. Basically the following:This didn't work. I did not receive any errors, but nothing changes in my cache. I triple checked my
cache.writeFragment
and confirmed it even worked in other parts of my code; but within thismerge
function it does nothing. It also didn't make a difference what I return from thismerge
function.Could I instead try
cache.writeFragment
in the settingsmerge
field policy ofGraph
? I replacedmerge: true
with a copy of thegraphSettingsUpdate
merge
function. It still did not create a normalized reference and was now also creating an infinite loop - repeatedly triggering themerge
function.So I thought why don't I just try forcing normalization on the first read in the settings
read
field policy ofGraph
? This didn't work. Trying to usecache.writeFragment
inside aread
field policy returns the following error:However, my
Graph
object in the cache now has a settings field! (Interesting the samecache.writeFragment
seems to do nothing inside amerge
function but succeeds (then throws an error) in aread
function.) What happens if I try wrapping thiscache.writeFragment
in atry {} catch {}
? Everything continues as normal and the settings are normalized. This is now what theread
settings
field policy looks like:However, even though I am returning the newly created ref, the
Graph
does not have a reference toGraphSettings
in the cache.Now that settings are normalized I should have been able to update them using
cache.modify
orcache.writeFragment
from mymerge
functions, right? Nope. I confirmed both the MutationgraphSettingsUpdate
merge
field policy and theGraph
settings
merge
field policy are called andcache.modify
andcache.writeFragment
fail to update the normalizedGraphSettings
.So next I tried looking into my
mutate
function. One ofmutate
's options is to pass anupdate
function, which is passed an instance of the cache:And still nothing updates! Then, I thought maybe I should try just updating individual fields:
And it works! When checking my cache, the graph settings were pushed to the normalized
GraphSettings
. I don't understand why modifyingGraph
failed, though. I then tried the above workingcache.modify
in my MutationgraphSettingsUpdate
settings
merge
field policy just to see yet just like before the cache still had no updates.For now I suppose I'll use
update
andcache.modify
inside anymutations
- which isn't ideal.So, TLDR, the issues when using
@client
with normalization:cache.writeFragment
orcache.modify
inside amerge
field policy do not workmerge
field policy are not normalize if the field is localread
field policy are not normalized if the field is localoptimisticResponse
will trigger the MutationgraphSettingsUpdate
merge
field policy - butexistingData
is undefined,newData
is just a reference, andcache.modify
andcache.writeFragment
do not seem to workVersions
@apollo/client@3.3.12
The text was updated successfully, but these errors were encountered: