2
votes

I'm working with Apollo Client local state and cache and although I've gone through the docs (https://www.apollographql.com/docs/react/essentials/local-state), a couple of tutorials (for example, https://www.robinwieruch.de/react-apollo-link-state-tutorial/) and looked at some examples, I'm a bit befuddled. In addition to any insight you might be able provide with the specific questions below, any links to good additional docs/resources to put things in context would be much appreciated.

In particular, I understand how to store local client side data and retrieve it, but I'm not seeing how things integrate with data retrieved from and sent back to the server.

Taking the simple 'todo app' as a starting point, I have a couple of questions.

1) If you download a set of data (in this case 'todos') from the server using a query, what is the relationship between the cached data and the server-side data? That is, I grab the data with a query, it's stored in the cache automatically. Now if I want to grab that data locally, and, say, modify it (in this case, add a todo or modify it), how I do that? I know how to do it for data I've created, but not data that I've downloaded, such as, in this case, my set of todos. For instance, some tutorials reference the __typename -- in the case of data downloaded from the server, what would this __typename be? And if I used readQuery to grab the data downloaded from the server and stored in the cache, what query would I use? The same I used to download the data originally?

2) Once I've modified this local data (for instance, in the case of todos, setting one todo as 'completed'), and written it back to the cache with writeData, how does it get sent back to the server, so that the local copy and the remote copy are in sync? With a mutation? So I'm responsible for storing a copy to the local cache and sending it to the server in two separate operations?

3) As I understand it, unless you specify otherwise, if you make a query from Apollo Client, it will first check to see if the data you requested is in the cache, otherwise it will call the server. Why, then, do you need to make an @client in the example code to grat the todos? Because these were not downloaded from the server with a prior query, but are instead only local data?

const GET_TODOS = gql`
  {
    todos @client {
      id
      completed
      text
    }
    visibilityFilter @client
  }
`;

If they were in fact downloaded with an earlier query, can't you just use the same query that you used originally to get the data from the server, not putting @client, and if the data is in the cache, you'll get the cached data?

4) Lastly, I've read that Apollo Client will update things 'automagically -- that is, if you send modified data to the server (say, in our case, a modified todo) Apollo Client will make sure that that piece of data is modified in the cache, referencing it by ID. Are there any rules as to when it does and when it doesn't? If Apollo Client is keeping things in sync with the server using IDs, when do we need to handle it 'manually', as above, and when not?

Thanks for any insights, and if you have links to other docs than those above, or a good tutorial, I'd be grateful

1

1 Answers

1
votes
  1. The __typename is Apollo's built-in auto-magic way to track and cache results from queries. By default you can look up items in your cache by using the __typename and id of your items. You usually don't need to worry about __typename until you manually need to tweak the cache. For the most part, just re-run your server queries to pull from the cache after the original request. The server responses are cached by default, so the next time you run a query it will pull from the cache.

  2. It depends on your situation, but most of the time if you set your IDs properly Apollo client will automatically sync up changes from a mutation. All you should need to do is return the id property and any changed fields in your mutation query and Apollo will update the cache auto-magically. So, in the case you are describing where you mark a todo as completed, you should probably just send the mutation to the server, then in the mutation response you request the completed field and the id. The client will automatically update.

  3. You can use the original query. Apollo client essentially caches things using a query + variable -> results map. As long as you submit the same query with the same variables it will pull from the cache (unless you explicitly tell it not to).

  4. See my answer to #2 above, but Apollo client will handle it for you as long as you include the id and any modified data in your mutation. It won't handle it for you if you add new data, such as adding a todo to a list. Same for removing data.