when<R> method
R
when<R>({
- bool skipLoading = false,
- required R data(
- T data
- required R error(
- Object error,
- StackTrace stackTrace
- required R loading(),
- R none()?,
Allows you to define custom behavior for different states of an AsyncSnapshot
by providing callbacks for data, error, loading, and none.
dataCallbacks when snapshot hasTdata.errorCallbacks when snapshot hasError.loadingCallbacks when snapshot isLoading and hasNone.noneOptionally callbacks when snapshot not isLoading and hasNone.
Example:
snapshot.when(
data: (data) => Text('Data: $data'),
error: (error, stack) => Text('Error: $error'),
loading: () => CircularProgressIndicator(),
none: () => Text('No error or data'),
);
Use none for uncommon scenarios where data, error, and loading are
not applicable. For instance, to display a widget when there's no data, no
error, and no ongoing loading, or when a Stream is cancelled without
emitting any data or error (e.g Stream.empty).
If none is not provided:
loadingwill be called when init hasNone.- StateError will be thrown when done hasNone.
If skipLoading is true, loading won't be called when AsyncSnapshot
hasData or hasError. Instead, data or error will be called.
It's recommended to use isReloading in conjunction with skipLoading.
So all states are handled by ui.
Example:
Stack(
alignment: Alignment.center,
children: [
snapshot.when(
skipLoading: true,
data: (data) => Text('Data: $data'),
error: (error, stack) => Text('Error: $error'),
loading: () => CircularProgressIndicator(),
none: () => Text('No error or data'),
);
if(snapshot.isReloading)
Align(
alignment: Alignment.topCenter,
child: LinearProgressIndicator(),
),
],
)
Implementation
R when<R>({
bool skipLoading = false,
required R Function(T data) data,
required R Function(Object error, StackTrace stackTrace) error,
required R Function() loading,
R Function()? none,
}) {
if (isLoading && !skipLoading) return loading();
if (hasData) return data(this.data as T);
if (hasError) return error(this.error!, stackTrace!);
return switch (connectionState) {
ConnectionState.none => none != null ? none() : loading(),
ConnectionState.waiting => loading(),
ConnectionState.active => loading(),
ConnectionState.done when this.data is T => data(this.data as T),
_ => none != null ? none() : data(requireData),
};
}