Files
upstream-mirror 3a013ccdfe
Some checks failed
autofix.ci / autofix (push) Failing after 4s
Release / Release (push) Has been skipped
GitHub Actions Security Analysis / Run zizmor (push) Failing after 2s
snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:13:08 +05:00

5.6 KiB

id, title
id title
createMutation createMutation
function createMutation<TData, TError, TVariables, TContext>(options, queryClient?): CreateMutationResult<TData, TError, TVariables, TContext>;

Defined in: packages/svelte-query/src/createMutation.svelte.ts:171

Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects. createMutation is the function for that.

Type Parameters

TData

TData = unknown

TError

TError = Error

TVariables

TVariables = void

TContext

TContext = unknown

Parameters

options

Accessor<CreateMutationOptions<TData, TError, TVariables, TContext>>

The CreateMutationOptions to use, wrapped in an Accessor so options can be reactive.

queryClient?

Accessor<QueryClient>

Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used.

Returns

CreateMutationResult<TData, TError, TVariables, TContext>

mutate/mutateAsync also accept per-call onSuccess/onError/onSettled callbacks as a second argument, useful for triggering call-site side effects (e.g. navigation) without coupling them to the shared mutation definition. If you make multiple requests, onSuccess will fire only after the latest call you've made.

See

mutationOptions to share these options across multiple createMutation call sites, or to look the mutation up elsewhere via its mutationKey (e.g. with useMutationState).

Examples

<script lang="ts">
  import { createMutation, useQueryClient } from '@tanstack/svelte-query'

  const queryClient = useQueryClient()

  const addMutation = createMutation(() => ({
    mutationFn: addTodo,
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
  }))
</script>

<button
  onclick={() =>
    addMutation.mutate('Item', {
      onError: (error) => console.error('Failed to add item:', error),
    })
  }
>
  Add
</button>

Rendering the mutation's own state, rather than just firing it off:

<script lang="ts">
  import { createMutation, useQueryClient } from '@tanstack/svelte-query'

  const queryClient = useQueryClient()

  const addMutation = createMutation(() => ({
    mutationFn: addTodo,
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
  }))
</script>

{#if addMutation.isPending}
  Adding todo...
{:else}
  {#if addMutation.isError}
    <div>An error occurred: {addMutation.error.message}</div>
  {/if}
  <button onclick={() => addMutation.mutate('Item')}>Add</button>
{/if}

Optimistic update via onMutate, rolling back on onError:

<script lang="ts">
  import { createMutation, useQueryClient } from '@tanstack/svelte-query'

  const queryClient = useQueryClient()

  const addMutation = createMutation(() => ({
    mutationFn: addTodo,
    onMutate: async (newTodo: string) => {
      await queryClient.cancelQueries({ queryKey: ['todos'] })
      const previousTodos = queryClient.getQueryData<Array<string>>(['todos'])

      queryClient.setQueryData<Array<string>>(['todos'], (old) => [
        ...(old ?? []),
        newTodo,
      ])

      // Passed to `onError` as `onMutateResult` if the mutation fails.
      return { previousTodos }
    },
    onError: (_err, _newTodo, onMutateResult) => {
      queryClient.setQueryData(['todos'], onMutateResult?.previousTodos)
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['todos'] })
    },
  }))
</script>

<button onclick={() => addMutation.mutate('Item')}>Add</button>

Callbacks passed per call to mutate only fire for the last call — mutateAsync gives you a promise per call instead, so you can wait for all of them when they succeed:

<script lang="ts">
  import { createMutation, useQueryClient } from '@tanstack/svelte-query'

  const queryClient = useQueryClient()

  const addMutation = createMutation(() => ({
    mutationFn: addTodo,
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
  }))

  async function handleAddAll(todos: Array<string>) {
    try {
      await Promise.all(todos.map((todo) => addMutation.mutateAsync(todo)))
    } catch (error) {
      console.error('Failed to add todos:', error)
    }
  }
</script>

<button onclick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
  Add all
</button>

If some of the mutations above can fail independently of the others, and you want to know which ones did — rather than losing that information the moment the first one rejects — swap Promise.all for Promise.allSettled:

<script lang="ts">
  import { createMutation, useQueryClient } from '@tanstack/svelte-query'

  const queryClient = useQueryClient()

  const addMutation = createMutation(() => ({
    mutationFn: addTodo,
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
  }))

  async function handleAddAll(todos: Array<string>) {
    const addResults = await Promise.allSettled(
      todos.map((todo) => addMutation.mutateAsync(todo)),
    )

    addResults.forEach((addResult, index) => {
      if (addResult.status === 'rejected') {
        console.error(`Failed to add "${todos[index]}":`, addResult.reason)
      }
    })
  }
</script>

<button onclick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
  Add all
</button>