runSimple<T, E> method

Future<void> runSimple<T, E>({
  1. FutureOr<bool> shouldSubmit()?,
  2. FutureOr<void> afterShouldNotSubmit()?,
  3. FutureOr<void> beforeSubmit()?,
  4. required Future<T> submit(),
  5. FutureOr<void> afterSubmit(
    1. T
    )?,
  6. FutureOr<E?> mapError(
    1. Object
    )?,
  7. FutureOr<void> afterKnownError(
    1. E
    )?,
  8. FutureOr<void> afterError()?,
  9. bool isRetryable = true,
  10. bool skipIfInProgress = false,
})

Simplified and opinionated version of run that supports many common cases.

Example for not-so-uncommon case:

submitState.runSimple<String, LoginErrorType>(
  shouldSubmit: () async => await showConfirmationDialog() == true,
  afterShouldNotSubmit: () => showCancelledSnackBar(),
  beforeSubmit: () => clearErrors(),
  submit: () async => await logIn(email, password),
  afterSubmit: (result) => moveToHome(userName: result),
  mapError: (exception) => exception is LoginException ? exception.errorType : null,
  afterKnownError: (errorType) => passwordField.error = errorType.errorMessage,
  afterError: () => passwordField.value = null,
);

Parameters:

Implementation

Future<void> runSimple<T, E>({
  FutureOr<bool> Function()? shouldSubmit,
  FutureOr<void> Function()? afterShouldNotSubmit,
  FutureOr<void> Function()? beforeSubmit,
  required Future<T> Function() submit,
  FutureOr<void> Function(T)? afterSubmit,
  FutureOr<E?> Function(Object)? mapError,
  FutureOr<void> Function(E)? afterKnownError,
  FutureOr<void> Function()? afterError,
  bool isRetryable = true,
  bool skipIfInProgress = false,
}) async {
  if (skipIfInProgress && inProgress) return;
  if (shouldSubmit != null && !await shouldSubmit()) {
    await afterShouldNotSubmit?.call();
    return;
  }
  await run(() async {
    try {
      await beforeSubmit?.call();
      final result = await submit();
      await afterSubmit?.call(result);
    } catch (e) {
      await afterError?.call();
      final mappedError = await mapError?.call(e);
      if (mappedError != null) {
        await afterKnownError?.call(mappedError);
      } else {
        rethrow;
      }
    }
  }, isRetryable: isRetryable);
}