question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Merge function never brings existing value for an identified fragment on cache

See original GitHub issue

I have 2 queries which I use with the same variable/input, like this:

query GET_MY_DATA_FOO($id: String!) {
  foo(id: $id) {
    id
    ...Impagados
  }
}

query GET_MY_DATA_BAR($id: String!) {
  bar(id: $id) {
    id
    ...Impagados
  }
}

fragment Impagados on Impagados {
  impagados {
    id
    __typename
    ebe {
      error
      nota
    }
    icired {
      error
      nota
    }
    rai {
      error
      nota
    }
  }
}

I use it, let’s say:

const { data, error, loading } = useQuery(GET_MY_DATA_FOO, {
  variables: { id: '1' },
});

const { data, error, loading } = useQuery(GET_MY_DATA_BAR, {
  variables: { id: '1' },
});

Intended outcome:

I would expect my merge function to bring existing data from previous queries. This sample merge function triggers ok:

merge(existing = {}, incoming = {}, { cache, toReference, readField }) {
  if (existing) return { ...existing };
  return { ...incoming };
}

Actual outcome:

After GET_MY_DATA_FOO query was launched, retrieved the data, and triggered the merge function (with existing value undefined, of course), I launch GET_MY_DATA_BAR which comes with existing value undefined as well.

I have tried removing the id field from the fragment, so it wouldn’t become an entity, so to say, and I could maybe access the same fragment already cached on the other query. But I cannot find a way to do it.

If I keep the id field there, the merge function triggers, there is no existing value and trying to read the fragment from cache already brings the new value that was already written on cache:

const existing = cache.readFragment({
  id: incoming.__ref,
  fragment: gql`
    fragment Impagados on Impagados {
      id
      ebe {
        error
        nota
      }
      icired {
        error
        nota
      }
      rai {
        error
        nota
      }
    }
  `,
});

Versions

System: OS: Linux 5.4 Ubuntu 20.04.3 LTS (Focal Fossa) Binaries: Node: 14.15.0 - ~/.nvm/versions/node/v14.15.0/bin/node Yarn: 1.22.15 - ~/.nvm/versions/node/v14.15.0/bin/yarn npm: 8.1.3 - ~/.nvm/versions/node/v14.15.0/bin/npm Browsers: Chrome: 94.0.4606.71 npmPackages: @apollo/client: ~3.2.5 => 3.2.9

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
Richacinascommented, Nov 19, 2021

Thanks for your answer.

I’m not sure if this is a typo or an explanation…

Sorry, that was a typo.

What I’m trying to achieve is that, when the second query is launched, I can read the value that I got on the first query for this fragment. Once I have that, I would like to choose which one I keep.

Should I keep the __typename and id fields on this fragment in order to to that, or should I toss id so they stay separate? How could I get the value of the other fragment either way?

Thanks a lot

1reaction
Richacinascommented, Nov 23, 2021

Let me have a proper read about this again… I would like to keep talking about it as well.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Customizing the behavior of cached fields - Apollo GraphQL
A merge function that specifies what happens when field's cached value is written; An array of key arguments that help the cache avoid...
Read more >
Cache does not merge fragments correctly #8370 - GitHub
Fragment merges can result in the cache dropping fields, which ends up returning an empty value from useQuery when returnPartialData is off, ...
Read more >
Apollo GraphQL: use case for merge function in type policy?
This function reuses as many items from the existing array as possible, and takes an item from incoming otherwise. Equality is checked based ......
Read more >
RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
Abstract A Uniform Resource Identifier (URI) is a compact sequence of ... RFC 3986 URI Generic Syntax January 2005 integer values used by...
Read more >
Redux Essentials, Part 8: RTK Query Advanced Patterns
It takes three arguments: the name of the endpoint to update, the same cache key value used to identify the specific cached data,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found