MutationOptions<TData, TVariables, TOnMutateResult> class final Mutations

Everything that describes a mutation: the write it performs, its callbacks, and how it retries, pauses and queues.

Hand one to a MutationObserver (or the Flutter binding's mutation helpers). The three type arguments are what the function returns (TData), what it is called with (TVariables), and what onMutate returns (TOnMutateResult) — the rollback handle an optimistic update passes to onError and onSettled. A mutation with no optimistic step has no such result; simple spells that out as void so the other two types infer from mutationFn.

An optimistic update: patch the cache in onMutate, restore the snapshot in onError, and refetch the truth in onSettled:

final todosKey = QueryKey(['todos']);
final addTodo = MutationOptions<Todo, Todo, List<Todo>>(
  mutationFn: (Todo todo) => api.addTodo(todo),
  onMutate: (Todo todo) async {
    await client.cancelQueries(filters: QueryFilters(queryKey: todosKey));
    final previous = client.getQueryData<List<Todo>>(todosKey) ?? [];
    client.setQueryData<List<Todo>>(todosKey, [...previous, todo]);
    return previous;
  },
  onError: (error, stackTrace, todo, previous) {
    if (previous != null) client.setQueryData(todosKey, previous);
  },
  onSettled: (data, error, stackTrace, todo, previous) =>
      client.invalidateQueries(filters: QueryFilters(queryKey: todosKey)),
);

Every field is optional. An unset field takes the default registered for the mutation's key with QueryClient.setMutationDefaults, then the client's DefaultOptions.mutations, then the default each field states. The callbacks have no client-level default.

The order the callbacks run in: the cache-wide MutationCache.onMutate, then onMutate; after the function, MutationCache.onSuccess (or onError), then onSuccess (or onError), then MutationCache.onSettled, then onSettled. Each returned future is awaited before the next one runs, and the mutation stays pending until the last has completed. The per-call MutateCallbacks come after that.

No value equality, on purpose: options built inline are re-applied on every build, and the observer compares the resolved values — so inline callbacks are not a change by themselves.

Annotations
  • @immutable

Constructors

MutationOptions({QueryKey? mutationKey, MutationFn<TData, TVariables>? mutationFn, MutationFnWithContext<TData, TVariables, TOnMutateResult>? mutationFnWithContext, OnMutate<TVariables, TOnMutateResult>? onMutate, OnMutationSuccess<TData, TVariables, TOnMutateResult>? onSuccess, OnMutationError<TVariables, TOnMutateResult>? onError, OnMutationSettled<TData, TVariables, TOnMutateResult>? onSettled, RetryPolicy? retry, RetryDelay? retryDelay, NetworkMode? networkMode, GcTime? gcTime, MutationScope? scope, Object? meta})
Creates the options. Every field is optional; an unset field takes the client's default when the mutation is built. Pass at most one of mutationFn and mutationFnWithContext.
const

Properties

gcTime → GcTime?
How long a settled mutation stays in the cache once nothing observes it. Default GcTime.defaultValue, five minutes.
final
hashCode → int
The hash code for this object.
no setterinherited
meta → Object?
Arbitrary data carried along for logging, devtools or the callbacks; readable as Mutation.meta and MutationFunctionContext.meta. No default.
final
mutationFn → MutationFn<TData, TVariables>?
Runs the mutation. Left unset, the function registered for the key with setMutationDefaults (or in DefaultOptions.mutations) is used, and a mutation with none fails with MissingMutationFunctionError when it runs, without retrying.
final
mutationFnWithContext → MutationFnWithContext<TData, TVariables, TOnMutateResult>?
mutationFn with a second argument: the MutationFunctionContext of the run — the client, meta, the key, what onMutate returned, and a signal that Mutation.cancel cancels. Instead of mutationFn, never beside it — both at once fails an assertion at the constructor in a debug build, and is an ArgumentError when the client resolves the options in a release build; when set it also wins over a function registered with setMutationDefaults, which has no context form. No default.
final
mutationKey → QueryKey?
Groups mutations for the cache's filters, for isMutating, and for the defaults registered with QueryClient.setMutationDefaults. No default: a mutation without a key simply cannot be addressed by one.
final
networkMode → NetworkMode?
How connectivity gates the run. Default NetworkMode.online: submitted offline, the mutation pauses, and a mounted client resumes it on reconnect.
final
onError → OnMutationError<TVariables, TOnMutateResult>?
Runs when the mutation fails for good, retries spent, after the cache-wide MutationCache.onError, with what onMutate returned so an optimistic update can be rolled back. A returned future is awaited; a throw is reported to the zone and does not replace the original error. No default.
final
onMutate → OnMutate<TVariables, TOnMutateResult>?
Runs before the mutation function, when the mutation is submitted; its result is handed to onSuccess, onError and onSettled so an optimistic update can be rolled back. A returned future is awaited before the function runs; a throw fails the mutation without running the function. No default.
final
onSettled → OnMutationSettled<TData, TVariables, TOnMutateResult>?
Runs after onSuccess or onError and the cache-wide MutationCache.onSettled, with whichever of data and error applies. A returned future is awaited, and the mutation stays pending until it completes — return an invalidation's future to report success only once the refetch is done. No default.
final
onSuccess → OnMutationSuccess<TData, TVariables, TOnMutateResult>?
Runs when the mutation function succeeds, after the cache-wide MutationCache.onSuccess and before the result reports success. A returned future is awaited. Throwing here turns the success into an error. No default.
final
retry → RetryPolicy?
Whether a failed attempt is retried. Default RetryPolicy.never: mutations are rarely safe to repeat. (TanStack Query: retry: 0.)
final
retryDelay → RetryDelay?
How long to wait between attempts. Default RetryDelay.defaultValue: one second, doubling per attempt, at most thirty seconds.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
scope → MutationScope?
Mutations in the same scope run one at a time — see MutationScope, which says what waits (the function, not onMutate) and for how long (until the running one's onSettled has completed). No default: unscoped mutations run concurrently.
final

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Static Methods

simple<TData, TVariables>({QueryKey? mutationKey, MutationFn<TData, TVariables>? mutationFn, MutationFnWithContext<TData, TVariables, void>? mutationFnWithContext, OnMutationSuccess<TData, TVariables, void>? onSuccess, OnMutationError<TVariables, void>? onError, OnMutationSettled<TData, TVariables, void>? onSettled, RetryPolicy? retry, RetryDelay? retryDelay, NetworkMode? networkMode, GcTime? gcTime, MutationScope? scope, Object? meta}) → MutationOptions<TData, TVariables, void>
Options for a mutation without an onMutate step.