Optimistic updates and error handling in GraphQL

From the GraphQL cheat sheet · Mutations · verified Jul 2026

Optimistic updates and error handling

javascript
// Apollo Client mutation with optimistic response
import { gql, useMutation } from '@apollo/client';

const CREATE_POST = gql`
  mutation CreatePost($title: String!, $content: String!) {
    createPost(title: $title, content: $content) {
      id
      title
      content
      createdAt
      author {
        id
        name
      }
    }
  }
`;

function CreatePostForm() {
  const [createPost, { data, loading, error }] = useMutation(CREATE_POST, {
    // Optimistic response
    optimisticResponse: {
      createPost: {
        __typename: 'Post',
        id: 'temp-id',
        title: formData.title,
        content: formData.content,
        createdAt: new Date().toISOString(),
        author: {
          __typename: 'User',
          id: currentUser.id,
          name: currentUser.name
        }
      }
    },
    
    // Update cache after mutation
    update(cache, { data: { createPost } }) {
      cache.modify({
        fields: {
          posts(existingPosts = []) {
            const newPostRef = cache.writeFragment({
              data: createPost,
              fragment: gql`
                fragment NewPost on Post {
                  id
                  title
                  content
                  createdAt
                  author {
                    id
                    name
                  }
                }
              `
            });
            return [...existingPosts, newPostRef];
          }
        }
      });
    },
    
    // Error handling
    onError(error) {
      console.error('Mutation error:', error);
      toast.error('Failed to create post');
    },
    
    // Success handling
    onCompleted(data) {
      toast.success('Post created successfully');
      resetForm();
    }
  });
  
  const handleSubmit = async (e) => {
    e.preventDefault();
    
    try {
      await createPost({
        variables: {
          title: formData.title,
          content: formData.content
        }
      });
    } catch (err) {
      // Error is handled by onError
    }
  };
  
  return (
    <form onSubmit={handleSubmit}>
      {/* Form fields */}
      <button type="submit" disabled={loading}>
        {loading ? 'Creating...' : 'Create Post'}
      </button>
      {error && <p>Error: {error.message}</p>}
    </form>
  );
}
💡 Optimistic UI updates for better UX
⚡ Rollback on error automatically
📌 Error handling with try-catch
🔥 Cache updates after mutations

More GraphQL tasks

Back to the full GraphQL cheat sheet