LogoSignals.dart
Copy Markdown
rodydavis/signals.dart 999999

Type: AsyncSignal

API reference and details for AsyncSignal from signals.dart.

AsyncSignal#

Kind: class & function  |  Package: package:signals_core

Class: AsyncSignal#

A highly powerful Signal specifically designed for manual, imperative asynchronous state management.

Unlike declarative reactive signals like futureSignal or streamSignal (which automatically wrap and listen to an existing Future or Stream), AsyncSignal gives you full manual/imperative control over pushing async states (AsyncState.loading, AsyncState.data, and AsyncState.error) into the reactive graph.

This is the perfect state primitive for building custom repositories, handling manual user action triggers (e.g., submitting a registration form, calling an API on button click), or bridging low-level callback-based APIs into reactive states.

1. Imperative State Mutations#

You can update the state of the signal directly using specialized mutation helpers:

  • setLoading() puts the signal into a clean AsyncLoading state.
  • setValue(T data) pushes a new AsyncData state containing the data.
  • setError(Object error, [StackTrace? stackTrace]) transitions the signal to an AsyncError state.
final authState = asyncSignal<User>(AsyncState.loading());

Future<void> login(String email, String password) async {
  try {
    authState.setLoading(); // Set UI to loading state
    final user = await authApi.signIn(email, password);
    authState.setValue(user); // Push success data
  } catch (err, stack) {
    authState.setError(err, stack); // Push error state
  }
}

2. Awaiting Async Completion via .future#

An outstanding capability of AsyncSignal is its built-in .future getter. Any part of your code can await this future. It returns a standard Future that resolves when the signal next receives a data value, or throws if the signal next receives an error state.

final loginSignal = asyncSignal<User>(AsyncState.loading());

// Task A: Start background operation
Future.delayed(Duration(seconds: 2), () {
  loginSignal.setValue(User(name: 'Charlie'));
});

// Task B: Wait for the signal to resolve!
final user = await loginSignal.future; // Suspends execution until Task A completes!
print(user.name); // 'Charlie'

3. Rendering in Flutter using Watch and AsyncState Pattern matching#

In your Flutter widgets, you can seamlessly watch the signal and use Dart's native pattern matching on AsyncState to render different widgets corresponding to the current asynchronous lifecycle:

Widget build(BuildContext context) {
  final state = authState.watch(context);

  return state.map(
    data: (user) => HomeScreen(user: user),
    error: (error, stackTrace) => ErrorWidget(error),
    loading: () => const CircularProgressIndicator(),
  );
}

4. Bridging callback/event-driven systems via EventSink#

AsyncSignal implements Dart's standard EventSink interface. This allows it to act directly as an event sink for streams, websockets, or callback listeners:

final messageLog = asyncSignal<String>(AsyncState.loading());
final chatStream = webSocket.stream.map((event) => event.toString());

// Automatically push all incoming messages and errors from the stream into the signal:
chatStream.listen(
  (msg) => messageLog.add(msg),
  onError: (err) => messageLog.addError(err),
  onDone: () => messageLog.close(),
);
Favor AsyncSignal when you need manual, callback-driven, or button-press-triggered state mutations. For auto-triggering, declarative, or read-only asynchronous data dependencies (like pulling data when an ID changes), favor futureSignal or computedAsync instead.

Members of AsyncSignal#

Member Type Signature Description
AsyncSignal constructor dart AsyncSignal(super.value, {super.options}) A Signal that stores value in AsyncState
future method dart Future future The future of the signal completer
isCompleted method dart bool isCompleted Returns true if the signal is completed an error or data
setError method dart void setError(Object error, [StackTrace? stackTrace]) Set the error with optional stackTrace to AsyncError
setValue method dart void setValue(T value) Set the value to AsyncData
setLoading method dart void setLoading([AsyncState? state]) Set the loading state to AsyncLoading
reset method dart void reset([AsyncState? value]) Reset the signal to the initial value
init method dart void init() Initialize the signal
reload method dart Future reload() Reload the future
refresh method dart Future refresh() Refresh the future
value method dart AsyncState value
requireValue method dart T requireValue Returns the value of the signal

Function: asyncSignal#

AsyncSignal<T> asyncSignal(AsyncState<T> value, {AsyncSignalOptions<T>? options, @Deprecated('Use options: AsyncSignalOptions(name: ...) instead') String? debugLabel, @Deprecated('Use options: AsyncSignalOptions(autoDispose: ...) instead') bool? autoDispose})

Helper function to create an AsyncSignal initialized with an AsyncState.

Example#

// Create an AsyncSignal initialized to a loading state
final counter = asyncSignal<int>(AsyncState.loading());

// Create an AsyncSignal initialized with initial data
final status = asyncSignal<String>(AsyncState.data('Active'));

References#

The AsyncSignal type is referenced and used in the following pages: