mutateAsync method
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;
}
}