mutateAsync method

Future<T> mutateAsync(
  1. P params
)

Executes mutation returning the resolved data T or rethrowing the caught error.

Example:

try {
  final post = await createPost.mutateAsync({'title': 'Hello'});
} catch (e) {
  print('Failed: $e');
}

Implementation

Future<T> mutateAsync(P params) async {
  _status.value = MutationStatus.pending;
  _error.value = null;

  dynamic context;
  T? autoPreviousSnapshot;

  // 1. Automated Optimistic Update Snapshot & Application
  if (optimisticKey != null) {
    autoPreviousSnapshot = BloomData.getQueryData<T>(optimisticKey!);
    if (optimisticData != null) {
      BloomData.setQueryData<T>(
        optimisticKey!,
        (old) => optimisticData!(params, old),
      );
    }
  }

  // 2. Custom onMutate hook
  if (onMutate != null) {
    try {
      context = await onMutate!(params);
    } catch (err) {
      logger.warn('Error inside onMutate hook: $err');
    }
  }

  try {
    final result = await mutateFn(params);
    _data.value = result;
    _status.value = MutationStatus.success;
    _error.value = null;

    // 3. Automated Cache Invalidation
    for (final key in invalidateKeys) {
      BloomData.invalidateQueries(key);
    }

    if (onSuccess != null) {
      await onSuccess!(result, params, context);
    }
    if (onSettled != null) {
      await onSettled!(result, null, params, context);
    }

    return result;
  } catch (err, st) {
    logger.error('Mutation execution failed: $err', err, st);
    _error.value = err;
    _status.value = MutationStatus.error;

    // 4. Automated Optimistic Rollback
    if (optimisticKey != null) {
      logger.info('BloomMutation: Automatically rolling back optimistic update for [${BloomData.normalizeKey(optimisticKey!)}]');
      BloomData.setQueryData<T>(optimisticKey!, (_) => autoPreviousSnapshot);
    }

    if (onError != null) {
      await onError!(err, params, context);
    }
    if (onSettled != null) {
      await onSettled!(null, err, params, context);
    }

    rethrow;
  }
}