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

useQuery with cache-only does not receive data from another query of the same data #9383

Closed
jamesopti opened this issue Feb 2, 2022 · 10 comments
Labels

Comments

@jamesopti
Copy link
Contributor

jamesopti commented Feb 2, 2022

Intended outcome:

I am making two queries, one for a list of cats (via the network) and one for a single cat (via cache-only). I'm also subscribing to updates to all cats:

Queries
export const CAT_FIELDS_FRAGMENT = gql`
  fragment CatFields on Cat {
    id
    orgId
    name
  }
`

export const GET_CATS = gql`
  ${CAT_FIELDS_FRAGMENT}
  query GetCats($orgId: ID!) {
    cats(orgId: $orgId) {
      ...CatFields
    }
  }
`
export const GET_CATS_SUBSCRIPTION = gql`
  ${CAT_FIELDS_FRAGMENT}
  subscription SubscribeToCats($orgId: ID!) {
    allCats(orgId: $orgId) {
      ...CatFields
    }
  }
`
export const GET_CAT = gql`
  ${CAT_FIELDS_FRAGMENT}
  query GetCat($id: ID!, $orgId: ID!) {
    cat(id: $id, orgId: $orgId) {
      ...CatFields
    }
  }
`
const { data: cats, subscribeToMore } = useQuery(GET_CATS, {
  variables: { orgId: 'org1' },
  fetchPolicy: 'cache-and-network',
  partialRefetch: true,
  returnPartialData: true,
})
subscribeToMore({
  document: GET_CATS_SUBSCRIPTION,
  updateQuery: (prev, { subscriptionData }) => {
    if (!subscriptionData.data || !subscriptionData.data.cats) return prev

    // Result here will be merged based on the cats merge policy
    return subscriptionData.data
  },
})

const { data: cat1 } = useQuery(GET_CAT, {
  variables: { id: 'cat1', orgId: 'org1' },
  fetchPolicy: 'cache-only',
  nextFetchPolicy: 'cache-only',
  partialRefetch: true,
  returnPartialData: true,
})

I would expect that on initial page load and any subscription updates to cats that my singular cat query will always update based on the cache value supplied by the cats query/subscription

Actual outcome:

The singular useQuery is never supplied any data.

How to reproduce the issue:

See code above

Workaround:

Manually updating the cache like this appears to achieve the desired outcome:

useEffect(() => {
  if (!cats || !cats.cats) return
  // Update the apollo cache for the individual cat queries here
  // so that consumers of `useGetCatQuery` will get notified of changes
  cats.cats.forEach((cat) => {
    apolloClient.cache.writeQuery({
      query: GET_CATS,
      variables: {
        id: cat.id,
        orgId: 'org1',
      },
      data: {
        cat,
      },
    })
  })
}, [apolloClient, cats])

Versions
➜ client git:(main) ✗ yarn info @apollo/client
└─ @apollo/client@npm:3.5.8
├─ Instances: 1
├─ Version: 3.5.8

System:
OS: macOS 12.0.1
Binaries:
Node: 16.13.0 - ~/.nvm/versions/node/v16.13.0/bin/node
Yarn: 2.4.3 - ~/.nvm/versions/node/v16.13.0/bin/yarn
npm: 8.1.0 - ~/.nvm/versions/node/v16.13.0/bin/npm
Browsers:
Chrome: 97.0.4692.99
Safari: 15.1

@am-a
Copy link

am-a commented Feb 2, 2022

Can you post both queries? Does the subscription have all the same data as the initial query? If not can you put returnPartialData on the initial query and see if that makes a difference?

@jamesopti
Copy link
Contributor Author

Can you post both queries?

Added them at the top inside a disclosure!

Does the subscription have all the same data as the initial query?

It does (using Fragments). See the queries

If not can you put returnPartialData on the initial query and see if that makes a difference?

Both the initial query and the individual query already have that option set to true.

@atarek12
Copy link

atarek12 commented Feb 2, 2022

I think the problem here is you are requesting a different query that was not requested before (GET_CAT). But apollo will hit the cache first if you are requesting the same query with the same variables.

I suggest instead of using useQuery, you can use client.readFragment instead, you can find it in the documentation here

@jamesopti
Copy link
Contributor Author

I suggest instead of using useQuery, you can use client.readFragment instead, you can find it in the documentation here

The reason for using useQuery is for each consuming react component to update when the value changes.

readFragment will only read the current cache value at a point in time.

I suppose a useCache() hook would work, but there is no such thing.

@atarek12
Copy link

atarek12 commented Feb 3, 2022

I got your point, I think your workaround is the best at the moment. also, you can track this issue. it introduces an useFragment() hook that will be subscribed to an observable.

@anthonyvalera
Copy link

Had a similar issue and was able to figure out a solution thanks to this SO answer and this section in the Apollo Docs

@jamesopti In your example, you'd want to provide a cache redirect like so:

const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        getCat(_, { args, toReference }) {
          return toReference({ __typename: 'Cat', id: args.id, orgId: args.orgId });
        },
      },
    },
  },
});

@jpvajda
Copy link
Contributor

jpvajda commented Aug 17, 2022

@jamesopti 👋 let me know if you feel this question is answered from the responses above.

@alessbell
Copy link
Member

Hi @jamesopti 👋 Were the suggestions above re: useFragment and cache redirects helpful in resolving your issue, or is there anything else we can answer for you? Thanks!

@alessbell alessbell added the 🏓 awaiting-contributor-response requires input from a contributor label Aug 1, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Sep 1, 2023

We're closing this issue now but feel free to ping the maintainers or open a new issue if you still need support. Thank you!

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Sep 1, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Oct 2, 2023

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
For general questions, we recommend using StackOverflow or our discord server.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

6 participants