Yashar Habibi
Yashar Habibi

Reputation: 1020

in apollo client pagination configuration with "merge" function, existing cached data always is empty even after calling fetchMore

I'm new to Apollo Client and I'm trying to implement pagination for my product list. but I can't figure out why the existing parameter in the merge function always returns empty. my incoming parameter always updates with a new list each time I call fetchMore but the existing parameter always is empty That's why I can't merge the new list with the old one.

this is my client configuration:

/* eslint-disable @typescript-eslint/no-unsafe-return */
import { ApolloClient, InMemoryCache } from '@apollo/client'
import { AppEndpoints } from './const'
import { createLink } from './links'


const cache = new InMemoryCache({
  typePolicies: {
    ListProductSearchType: {
      fields: {
        items: {
          keyArgs: false,
          // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
          merge: (existing = [], incoming, { args }) => {
            console.log('>>>args', args)
            console.log('>>>existing', existing) // it's always empty
            console.log('>>>incoming', incoming)

            return [...existing, ...incoming]
            
          },
       
        },
      },
    },
  
  },
})

const link = createLink(AppEndpoints.main)

const client = new ApolloClient({
  cache,
  // ssrMode: false,
  link,
  defaultOptions: {
    mutate: {
      errorPolicy: 'ignore',
    },
    query: {
      fetchPolicy: 'cache-first',
    },
  },
})

export default client

this is my Graphql response:

{
  "data": {
    "productSearch": {
      "listDto": {
        "count": 10,
        "items": [
          {
            "id": "1d37d4fe-79d9-440a-8869-2dca0327791b",
            "code": "780133 Iceland Poppy",
            "isMyfavorite": false,
            "currency": "$",
            "imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
            "price": 429.29,
            "compareAtPrice": 240.4,
            "hasDiscount": true,
            "visited": 27685,
            "salesCount": 8148,
            "createdDateTime": "2020-12-14T06:02:38.0469339+00:00",
            "__typename": "ProductSearchDto"
          },
          {
            "id": "ae15c925-75ef-4dde-aa07-0eeb1bbb75c8",
            "code": "330338 Amaranth",
            "isMyfavorite": false,
            "currency": "$",
            "imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
            "price": 234.8,
            "compareAtPrice": 211.32,
            "hasDiscount": true,
            "visited": 27660,
            "salesCount": 6374,
            "createdDateTime": "2020-12-05T15:04:37.4237772+00:00",
            "__typename": "ProductSearchDto"
          },
          {
            "id": "de23a1f8-5e79-4cf9-88f0-57518c42a82c",
            "code": "690156 Snowflake",
            "isMyfavorite": false,
            "currency": "$",
            "imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
            "price": 110.11,
            "compareAtPrice": 88.09,
            "hasDiscount": true,
            "visited": 27141,
            "salesCount": 2278,
            "createdDateTime": "2020-10-18T11:27:38.0467775+00:00",
            "__typename": "ProductSearchDto"
          },
          {
            "id": "fb298a9c-a3d7-4c0e-a96e-a552b98d340f",
            "code": "375033 Peony",
            "isMyfavorite": false,
            "currency": "$",
            "imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
            "price": 337.68,
            "compareAtPrice": 151.96,
            "hasDiscount": true,
            "visited": 27050,
            "salesCount": 2483,
            "createdDateTime": "2020-12-06T22:57:37.4236274+00:00",
            "__typename": "ProductSearchDto"
          },
          {
            "id": "d017638f-3062-49bf-99cc-0e06ba0882b9",
            "code": "112093 Hyacinth, wild",
            "isMyfavorite": false,
            "currency": "$",
            "imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
            "price": 460.43,
            "compareAtPrice": 326.91,
            "hasDiscount": true,
            "visited": 26843,
            "salesCount": 530,
            "createdDateTime": "2020-11-10T23:13:37.4235865+00:00",
            "__typename": "ProductSearchDto"
          },
          {
            "id": "682a3c04-a462-4cbd-be8f-8b65d024b73f",
            "code": "914276 Iceland Poppy",
            "isMyfavorite": false,
            "currency": "$",
            "imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
            "price": 126.81,
            "compareAtPrice": 100.18,
            "hasDiscount": true,
            "visited": 24055,
            "salesCount": 6328,
            "createdDateTime": "2021-01-05T11:05:38.0469862+00:00",
            "__typename": "ProductSearchDto"
          },
          {
            "id": "c48819e2-52f4-4324-9f11-616efbc1a744",
            "code": "494847 Persian Candytuft",
            "isMyfavorite": false,
            "currency": "$",
            "imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
            "price": 405.95,
            "compareAtPrice": 288.22,
            "hasDiscount": true,
            "visited": 23713,
            "salesCount": 7474,
            "createdDateTime": "2020-10-23T16:24:37.4236199+00:00",
            "__typename": "ProductSearchDto"
          },
          {
            "id": "7118ddd5-56cf-4e12-9665-accb5abf3f73",
            "code": "682251 Violet",
            "isMyfavorite": false,
            "currency": "$",
            "imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
            "price": 184.09,
            "compareAtPrice": 90.2,
            "hasDiscount": true,
            "visited": 23448,
            "salesCount": 6196,
            "createdDateTime": "2020-10-12T08:36:38.0469107+00:00",
            "__typename": "ProductSearchDto"
          },
          {
            "id": "9e69b51a-560e-4d5e-b956-d9438d996c61",
            "code": "982376 Calendula",
            "isMyfavorite": false,
            "currency": "$",
            "imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
            "price": 62.25,
            "compareAtPrice": 38.6,
            "hasDiscount": true,
            "visited": 23300,
            "salesCount": 9072,
            "createdDateTime": "2020-10-10T14:24:38.0463778+00:00",
            "__typename": "ProductSearchDto"
          },
          {
            "id": "623dde57-8daf-4637-b2d3-0ebbf166aad0",
            "code": "138453 Manchineel",
            "isMyfavorite": false,
            "currency": "$",
            "imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
            "price": 121.92,
            "compareAtPrice": 56.08,
            "hasDiscount": true,
            "visited": 22373,
            "salesCount": 4735,
            "createdDateTime": "2020-10-11T12:04:37.4235489+00:00",
            "__typename": "ProductSearchDto"
          }
        ],
        "__typename": "ListProductSearchType"
      },
      "__typename": "GenericQueryResponseProductSearchType"
    }
  }
}

and this is my query:

export const GetProductSearchDocument = /*#__PURE__*/ gql`
    query GetProductSearch($filter: GenericFilterRequestProductSearchReqInputType!) {
  productSearch(filter: $filter) {
    listDto {
      count
      items {
        id
        code
        isMyfavorite
        currency
        imageUrl
        price
        compareAtPrice
        hasDiscount
        visited
        salesCount
        createdDateTime
      }
    }
  }
}

i'm calling fetchMore like this:

 const [pageIndex, setpageIndex] = useState(0)
  const { productResults, loading, fetchMore } = useQueryProductSearchData()
  // eslint-disable-next-line @typescript-eslint/unbound-method
  const { formatMessage } = useIntl()

  useEffect(() => {
    if (pageIndex !== 0) {
      fetchMore({
        variables: {
          filter: {
            pageSize: 10,
            pageIndex,
            dto: {
              filters: [],
            },
          },
        },
      })
    }
  }, [fetchMore, pageIndex])

  const onViewMore = () => {
    setpageIndex((pre: any) => pre + 1)
  }

Upvotes: 3

Views: 1593

Answers (2)

tykatyk
tykatyk

Reputation: 263

You should add read function to your field policy

const cache = new InMemoryCache({
  typePolicies: {
    ListProductSearchType: {
      fields: {
        items: {
          //your code here
          //then add this function
          read(existing) {
            return existing
          },
        },
      },
    },
  },
})

Upvotes: -1

meez
meez

Reputation: 4788

Try adding keyFields: [], like:

typePolicies: {
    ListProductSearchType: {
      keyFields: [],
      fields: {
        items: {
          keyArgs: false,
          // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
          merge: (existing = [], incoming, { args }) => {
            console.log('>>>args', args)
            console.log('>>>existing', existing) // it's always empty
            console.log('>>>incoming', incoming)

            return [...existing, ...incoming]
            
          },
       
        },
      },
    },
  
  },

Upvotes: 3

Related Questions