graphqlapolloreact-apolloapollo-clientoptimistic-ui

Apollo client: Making optimistic updates while creation is still in progress


I want to be able to do updates on an object while it is still being created.

For example: Say I have a to-do list where I can add items with names. I also want to be able to edit names of items.

Now say a user with a slow connection creates an item. In that case I fire off a create item mutation and optimistically update my UI. That works great. So far no problem

Now let's say the create item mutation is taking a bit of time due to a slow network. In that time, the user decides to edit the name of the item they just created. For an ideal experience:

  1. The UI should immediately update with the new name
  2. The new name should eventually be persisted in the server

I can achieve #2 by waiting for the create mutation to finish (so that I can get the item ID), then making an update name mutation. But that means parts of my UI will remain unchanged until the create item mutation returns and the optimistic response of the update name mutation kicks in. This means #1 won't be achieved.

So I'm wondering how can I achieve both #1 and #2 using Apollo client.

Note: I don't want to add spinners or disable editing. I want the app to feel responsive even with a slow connection.


Solution

  • If you have access to the server you can implement upsert operations, and you can reduce all queries to the such one:

    mutation {
      upsertTodoItem(
        where: {
          key: $itemKey # Some unique key generated on client
        }
        update: {
          listId: $listId
          text: $itemText
        }
        create: {
          key: $itemKey
          listId: $listId
          text: $itemText
        }
      ) {
        id
        key
      }
    }
    

    So you will have a sequence of identical mutations differing only in variables. An optimistic response accordingly, can be configured to this one mutation. On the server you need to check if an item with such a key already exists and create or update an item respectively.

    Additionally you might want to use apollo-link-debounce to reduce number of requests when user is typing.