mutation<T> method

Mutation<T> mutation<T>()

Allows you to trigger and watch Futures (called mutations, since they often mutate some state) from within the build function. See the documentation for more.

Note: mutate() and clear() should not be called directly from within build, but rather from within some callback.

Implementation

Mutation<T> mutation<T>() {
  final (getValue, setValue) = use.data<AsyncValue<T>?>(null);

  // NOTE: we convert to a stream here because we can cancel
  // a stream subscription; there is no builtin way to cancel a future.
  final (future, setFuture) = use.state<Future<T>?>(null);
  final asStream = use.memo(() => future?.asStream(), [future]);

  use.effect(
    () {
      setValue(
        asStream == null ? null : AsyncLoading(getValue()?.data ?? None<T>()),
      );

      final subscription = asStream?.listen(
        (data) => setValue(AsyncData(data)),
        onError: (Object error, StackTrace trace) => setValue(
          AsyncError(error, trace, getValue()?.data ?? None<T>()),
        ),
      );

      return () => subscription?.cancel();
    },
    [asStream],
  );

  return (
    state: getValue(),
    mutate: setFuture,
    clear: () => setFuture(null),
  );
}