Trouble with `useQuery` - 'cache-only' not receiving updates?

Hello,

I have a question regarding the usage of useQuery, I’m not sure if I have something misconfigured or if I am just misunderstanding how it behaves under the hood.

The query I’m working with looks like this (GET_METADATA_LISTING):

    query($filter: String, $limit: Int, $offset: Int, $sortBy: [String], $sortOrder: [String]) {
        getMetadataListing(
            filter: $filter 
            published: false 
            first: $limit
            after: $offset
            sortBy: $sortBy
            sortOrder: $sortOrder
        ) @connection(key: "CatalogQuery")  {
            edges {
                node {
                    id
                    documentName
                    catalog
                    cumulusId
                    modificationDate
                	asset {
                        ... on asset {
                            id
                            fullpath
                        }
                    }
                    ...object_MetadataFragment @nonreactive
                    ...AttributesFragment
                }
            }
            totalCount
        }
    }

I am using this with useLazyQuery and executing the query after the app initializes. I’m using the @connection directive to control the cacheKey that the query stores under (I think this is correct procedure, please tell me if I’m off).

    const [
        getItems, 
        { fetchMore, refetch, error, data, loading, client  }
    ] = useLazyQuery(GET_METADATA_LISTING, {
        fetchPolicy: 'network-only',
        // context: { connectionVariables: ['key'] } // >> should this be provided here?
    });

In a separate react component, I am looking to use the cached data from this same query to get the totalCount from the cached response and display it. The component that uses this chunk of code mounts at the same time as the useLazyQuery one does - just no data is expected to exist yet.

    const { loading, error, data } = useQuery(GET_METADATA_LISTING, {
        fetchPolicy: 'cache-only',

        // NOTE: options I was trying, none seemed to help
        // nextFetchPolicy: 'cache-only',
        // context: { connectionVariables: ['key'] },
        // returnPartialData: true,
        // errorPolicy: 'ignore',
    });

I suppose overall what I am expecting to happen here is the useQuery call that uses GET_METADATA_LISTING would receive the updated cached data and redraw after the separate useLazyQuery retrieves the data and updates the cache.

Is this a reasonable expectation, or am I maybe misunderstanding the behavior here? Maybe my strategy here is completely off base?

If someone has some insight to share (or can nudge me in a more correct direction) it would be much appreciated!

My gut feeling is that this should work, but before we go down debugging this path: Is there a reason that you are not using useFragment here? That seems to be more suited for this kind of job, and would even allow you to just subscribe to only the totalCount.

Hey there thanks for the response.

I had a whole reply typed up, but had a nagging feeling there was something I was overlooking when I discovered my fragment seemingly always showing the previous value than what was expected (and what was currently present in the cache).

After a good bit of head scratching I believe I discovered why; the hook I had made to lazily call getMetadataListing contained a client.clearStore() before calling a refetch when variables change. This unsurprisingly seemed to be breaking the cache subscription behavior, so the updates to the store were not being picked up.

I removed the clearStore call and this resolved not only the fragment that was lagging, but my original strategy combining useQuery with cache-only as well.

Hope this helps someone in the future!

1 Like