From c2ef164ff2b7bbd7d71a534cb5f3401dc752dd15 Mon Sep 17 00:00:00 2001 From: Matchu Date: Mon, 21 Jun 2021 13:48:45 -0700 Subject: [PATCH] Cache item search pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ah right okay, when the `ItemSearchResultV2` doesn't have an `id`, Apollo Cache isn't quite so strong about caching conflicting-y fields, like the different parameterizations of `items`. With this change, we give the search result object an ID, which helps Apollo cache more confidently! It's just a serialization of the relevant search fields 😅 --- src/app/ItemSearchPage.js | 1 + src/server/types/Item.js | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/app/ItemSearchPage.js b/src/app/ItemSearchPage.js index e425888..38ca1f9 100644 --- a/src/app/ItemSearchPage.js +++ b/src/app/ItemSearchPage.js @@ -138,6 +138,7 @@ function ItemSearchPageResults({ query: latestQuery, offset }) { currentUserOwnsOrWants: $currentUserOwnsOrWants zoneIds: $zoneIds ) { + id numTotalItems items(offset: $offset, limit: 30) { id diff --git a/src/server/types/Item.js b/src/server/types/Item.js index 5034626..042551e 100644 --- a/src/server/types/Item.js +++ b/src/server/types/Item.js @@ -178,6 +178,7 @@ const typeDefs = gql` # TODO: I guess I didn't add the NC/NP/PB filter to this. Does that cause # bugs in comparing results on the client? type ItemSearchResultV2 { + id: ID! query: String! zones: [Zone!]! items(offset: Int, limit: Int): [Item!]! @@ -735,7 +736,22 @@ const resolvers = { } bodyId = petType.bodyId; } - return { query, bodyId, itemKind, currentUserOwnsOrWants, zoneIds }; + + // These are the fields that define the search! We provide them to the + // ItemSearchResultV2 resolvers, and also stringify them into an `id` for + // caching the search result. (We define the ID for caching here, rather + // than in the resolver or with a custom cache key on the client, to + // make it hard for the ID and relevant search fields to get out of sync!) + const fields = { + query, + bodyId, + itemKind, + currentUserOwnsOrWants, + zoneIds, + }; + const id = JSON.stringify(fields); + + return { id, ...fields }; }, itemSearchToFit: async ( _,