Skip to main content

Apollo client - cache APIs - auto update cache - erase cache - reactive variables - deletion - addition

Apollo Client 3 

  1. Local only fields
  2. Reactive Variables


const cache = new InMemoryCache({
  typePolicies: {
    Todo: {
      // If one of the keyFields is an object with fields of its own, you can
      // include those nested keyFields by using a nested array of strings:
      keyFields: ["date", "user", ["email"]],
    }
  },
});
  • This internal data is intended to be easily JSON-serializable, so you can take a snapshot with cache.extract(), save it somewhere, and later restore with cache.restore(snapshot).

Here’s a mutation called EditTodo that returns the new todo value in the mutation response.

mutation EditTodo ($id: Int!, $text: String!) {
  editTodo (id: $id, text: $text) {
    success
    todo {          # <- Returning it here
      id
      text 
      completed
    }
    error {
      ... on TodoNotFoundError {
        message
      }
      ... on TodoValidationError {
        message
      }
    }
  }
}
And without any further intervention on our part, the Apollo Client should automatically merge the response data into the cache because it recognizes the Todo:3 identifier that was returned by the earlier query.

How to ensure Apollo Client updates the cache

In order for Apollo Client to update the cache automatically, we have to remember to always return the new data in operation responses.

For query responses, that’s the point. The entire purpose of a query is to return data and cache it.

But for mutations, like editTodo that change a single entity, we should be able to update the item automatically if we return the value in the mutation response.

Instead, we might want to erase the entire cache. You can do that with the client.clearStore() method in the update function.

import { gql, useMutation } from "@apollo/client"
import { client } from "./client"

const LOGOUT = gql`
  mutation Logout {
    logout {
      success
      message
    }
  }
`

const Navbar = () => {
  const [logout] = useMutation(LOGOUT, {
	  update () {
	    client.clearStore()
	  }
	});

  return <div onClick={() => logout()}></div>
}
reactive variables:
https://www.apollographql.com/blog/local-state-management-with-reactive-variables
deletion
const [mutate, { data, error }] = useMutation<
  DeleteTodoTypes.DeleteTodo, 
  DeleteTodoTypes.DeleteTodoVariables
>(
  DELETE_TODO,
  {
    update (cache, el) {
      const deletedId = el.data?.deleteTodo.todo?.id
      const allTodos = cache.readQuery<GetAllTodos>({ query: GET_ALL_TODOS });

      cache.writeQuery({
        query: GET_ALL_TODOS,
        data: {
          todos: allTodos?.todos.filter((t) => t?.id !== deletedId)
        }
      });

      cache.evict({ id: el.data?.deleteTodo.todo?.id })
    }
  }
)

additions:
const [mutate, { data, error }] = useMutation<
    AddTodoTypes.AddTodo, 
    AddTodoTypes.AddTodoVariables
  >(
    ADD_TODO,
    {
      update (cache, { data }) {
        const newTodoFromResponse = data?.addTodo.todo;
        const existingTodos = cache.readQuery<GetAllTodos>({
          query: GET_ALL_TODOS,
        });

        if (existingTodos && newTodoFromResponse) {
          cache.writeQuery({
            query: GET_ALL_TODOS,
            data: {
              todos: [
                ...existingTodos?.todos,
                newTodoFromResponse,
              ],
            },
          });
        }
      }
    }
  )


https://www.apollographql.com/blog/demystifying-cache-normalization/

 https://kulkarniankita9.medium.com/oh-hello-apollo-client-goodbye-redux-49dfdeda16d1


Comments

Popular posts from this blog

for loop in javascript - promise - .eslintrc for "for of"

the vast majority of cases  map ,  forEach ,  find  etc. can be used.  async function printFiles () { const files = await getFilePaths(); await Promise.all(files. map (async (file) => { const contents = await fs.readFile(file, 'utf8') console.log(contents) })); } const inventory = [ { name : 'apples' , quantity : 2 } , { name : 'bananas' , quantity : 0 } , { name : 'cherries' , quantity : 5 } ] ; const result = inventory . find ( ( { name } ) => name === 'cherries' ) ;   function getFirstMatching(array) { for (let item of array) { const result = heavyTransform(item); if (result) { return result; } } } Specifically this shuts down the whole no-restricted-syntax. If you want to cherry-pick, here is the current definition: 'no-restricted-syntax' : [ 'error' , { selector : 'ForInStatement' , message...

fs.writeFile - permission issue on GCP (Google Cloud Run)

error on this: fs . writeFile ( fileName , pdfBytes , err => { if ( err ) { console . log ( err . message ) reject ( err . message ) } else resolve ( fileName ) }) #1 It looks like when deployed into Cloud Run it also requires the extra permission "Service Account Token Creator" to run  getSignedUrl . Locally for some reason this role is not required. #2 Only the directory  /tmp  is writable in Cloud Run. So, change the default write location to write into this directory. However, you have to be aware of 2 things: Cloud Run is stateless, that means when a new instance is created, the container start from scratch, with an empty  /tmp  directory /tmp  directory is an in-memory file system. The maximum allowed memory on Cloud Run is 2Gb, your app memory footprint included. In addition of your file and Airflow, not sure that you will have a lot of space. A final remark. Cloud Run is active only when it...

add new site to Vagrant Homestead

Homestead.yaml: folders : - map : ~/ freshinup to : / home / vagrant / code sites : - map : smartmotors . local . com to : / home / vagrant / code / smartmotors / public php : "7.3" - map : arbor . test to : / home / vagrant / code / arbor / public php : "7.3" /etc/hosts: 192.168.10.10 arbor.test 192.168.10.10 smartmotors.local.com vagrant up --provision php artisan smartmotors:seed --quickstart