ccnat
ccnat

Reputation: 125

Apollo-client update cache variable: orderby name doesn't work

I have a mutation of new product. I update cache with cache.writeQuery and I want to order the product by name. My code doesn't work, always the new product is the last item (see the picture) . I can see the error. Could you help me? What is wrong?

COMPONENT NEW PRODUCT

import { gql, useMutation } from '@apollo/client'

const NEW_PRODUCT = gql`
mutation newProduct($input: ProductInput) {
  newProduct(input:$input) {
    id
    name
    stock
    price
    date_creation
  }
}`

const GET_PRODUCTS = gql`
  query getProducts{
  getProducts{
    id
    name
    stock
    price
  }
}`

const NouProducte = () => {

  const [newProduct] = useMutation(NEW_PRODUCT, {
    update(cache, { data: { newProduct } }) {
      const { getProducts } = cache.readQuery({ query: GET_PRODUCTS })
      cache.writeQuery({
        query: GET_PRODUCTS,
        data: {
          getProducts: [...getProducts, newProduct],
          variables: { orderBy: name }
        }
      })
    }
  })
}

enter image description here

Upvotes: 0

Views: 1216

Answers (2)

xadm
xadm

Reputation: 8418

Why do you ever expected sorting?

You're using a low level access to cache then you're responsible for providing data in the same shape as expected from remote source.

In this case if source data was sorted you have to pass sorted data to be written. Just get getProducts, push newProduct into the array, sort it and finally use sorted array in writeQuery.

Upvotes: 0

Sir Codes Alot
Sir Codes Alot

Reputation: 1169

I am not sure if you can order-by on local cache with apollo. However, this is how I would resolve the issue:

  data: {
          getProducts: [...getProducts, newProduct]
        }

In this line of code you are adding all the original products, then the new product to the end of the array that you are writing to your cache.

A quick way to fix this is sort the array before writing it to the cache. The following compare sorts arrays by objects name attribute

  function compare(a, b) {
    // Use toUpperCase() to ignore character casing
    const productA = a.name.toUpperCase();
    const productB = b.name.toUpperCase();

    let comparison = 0;
    if (productA > productB) {
      comparison = 1;
    } else if (productA < productB) {
      comparison = -1;
    }
    return comparison;
  }

Then use it on your array to sort.

  data: {
          getProducts: [...getProducts, newProduct].sort(compare)
        }

Upvotes: 1

Related Questions