Unverified Commit b494e71e authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Improve async builder docs (#15373)

parent 42e4e16b
...@@ -38,6 +38,7 @@ import 'framework.dart'; ...@@ -38,6 +38,7 @@ import 'framework.dart';
/// on change of stream by overriding [afterDisconnected] and [afterConnected]. /// on change of stream by overriding [afterDisconnected] and [afterConnected].
/// ///
/// [T] is the type of stream events. /// [T] is the type of stream events.
///
/// [S] is the type of interaction summary. /// [S] is the type of interaction summary.
/// ///
/// See also: /// See also:
...@@ -165,12 +166,17 @@ class _StreamBuilderBaseState<T, S> extends State<StreamBuilderBase<T, S>> { ...@@ -165,12 +166,17 @@ class _StreamBuilderBaseState<T, S> extends State<StreamBuilderBase<T, S>> {
/// received from the asynchronous computation. /// received from the asynchronous computation.
enum ConnectionState { enum ConnectionState {
/// Not currently connected to any asynchronous computation. /// Not currently connected to any asynchronous computation.
///
/// For example, a [FutureBuilder] whose [FutureBuilder.future] is null.
none, none,
/// Connected to an asynchronous computation and awaiting interaction. /// Connected to an asynchronous computation and awaiting interaction.
waiting, waiting,
/// Connected to an active asynchronous computation. /// Connected to an active asynchronous computation.
///
/// For example, a [Stream] that has returned at least one value, but is not
/// yet done.
active, active,
/// Connected to a terminated asynchronous computation. /// Connected to a terminated asynchronous computation.
...@@ -206,7 +212,15 @@ class AsyncSnapshot<T> { ...@@ -206,7 +212,15 @@ class AsyncSnapshot<T> {
/// Current state of connection to the asynchronous computation. /// Current state of connection to the asynchronous computation.
final ConnectionState connectionState; final ConnectionState connectionState;
/// Latest data received. Is null, if [error] is not. /// The latest data received by the asynchronous computation.
///
/// If this is non-null, [hasData] will be true.
///
/// If [error] is not null, this will be null. See [hasError].
///
/// If the asynchronous computation has never returned a value, this may be
/// set to an initial data value specified by the relevant widget. See
/// [FutureBuilder.initialData] and [StreamBuilder.initialData].
final T data; final T data;
/// Returns latest data received, failing if there is no data. /// Returns latest data received, failing if there is no data.
...@@ -221,20 +235,35 @@ class AsyncSnapshot<T> { ...@@ -221,20 +235,35 @@ class AsyncSnapshot<T> {
throw new StateError('Snapshot has neither data nor error'); throw new StateError('Snapshot has neither data nor error');
} }
/// Latest error object received. Is null, if [data] is not. /// The latest error object received by the asynchronous computation.
///
/// If this is non-null, [hasError] will be true.
///
/// If [data] is not null, this will be null.
final Object error; final Object error;
/// Returns a snapshot like this one, but in the specified [state]. /// Returns a snapshot like this one, but in the specified [state].
///
/// The [data] and [error] fields persist unmodified, even if the new state is
/// [ConnectionState.none].
AsyncSnapshot<T> inState(ConnectionState state) => new AsyncSnapshot<T>._(state, data, error); AsyncSnapshot<T> inState(ConnectionState state) => new AsyncSnapshot<T>._(state, data, error);
/// Returns whether this snapshot contains a non-null data value. /// Returns whether this snapshot contains a non-null [data] value.
///
/// This can be false even when the asynchronous computation has completed
/// successfully, if the computation did not return a non-null value. For
/// example, a [Future<void>] will complete with the null value even if it
/// completes successfully.
bool get hasData => data != null; bool get hasData => data != null;
/// Returns whether this snapshot contains a non-null error value. /// Returns whether this snapshot contains a non-null [error] value.
///
/// This is always true if the asynchronous computation's last result was
/// failure.
bool get hasError => error != null; bool get hasError => error != null;
@override @override
String toString() => 'AsyncSnapshot($connectionState, $data, $error)'; String toString() => '$runtimeType($connectionState, $data, $error)';
@override @override
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
...@@ -289,15 +318,15 @@ typedef Widget AsyncWidgetBuilder<T>(BuildContext context, AsyncSnapshot<T> snap ...@@ -289,15 +318,15 @@ typedef Widget AsyncWidgetBuilder<T>(BuildContext context, AsyncSnapshot<T> snap
/// pipeline. /// pipeline.
/// ///
/// Changing the [StreamBuilder] configuration to another stream during event /// Changing the [StreamBuilder] configuration to another stream during event
/// generation introduces snapshot pairs of the form /// generation introduces snapshot pairs of the form:
/// ///
/// * `new AsyncSnapshot<int>.withData(ConnectionState.none, 5)` /// * `new AsyncSnapshot<int>.withData(ConnectionState.none, 5)`
/// * `new AsyncSnapshot<int>.withData(ConnectionState.waiting, 5)` /// * `new AsyncSnapshot<int>.withData(ConnectionState.waiting, 5)`
/// ///
/// The latter will be produced only when the new stream is non-null. The former /// The latter will be produced only when the new stream is non-null, and the
/// only when the old stream is non-null. /// former only when the old stream is non-null.
/// ///
/// The stream may produce errors, resulting in snapshots of the form /// The stream may produce errors, resulting in snapshots of the form:
/// ///
/// * `new AsyncSnapshot<int>.withError(ConnectionState.active, 'some error')` /// * `new AsyncSnapshot<int>.withError(ConnectionState.active, 'some error')`
/// ///
...@@ -331,7 +360,6 @@ typedef Widget AsyncWidgetBuilder<T>(BuildContext context, AsyncSnapshot<T> snap ...@@ -331,7 +360,6 @@ typedef Widget AsyncWidgetBuilder<T>(BuildContext context, AsyncSnapshot<T> snap
/// case ConnectionState.waiting: return new Text('Awaiting bids...'); /// case ConnectionState.waiting: return new Text('Awaiting bids...');
/// case ConnectionState.active: return new Text('\$${snapshot.data}'); /// case ConnectionState.active: return new Text('\$${snapshot.data}');
/// case ConnectionState.done: return new Text('\$${snapshot.data} (closed)'); /// case ConnectionState.done: return new Text('\$${snapshot.data} (closed)');
/// default: throw "Unknown: ${snapshot.connectionState}";
/// } /// }
/// }, /// },
/// ) /// )
...@@ -391,14 +419,15 @@ class StreamBuilder<T> extends StreamBuilderBase<T, AsyncSnapshot<T>> { ...@@ -391,14 +419,15 @@ class StreamBuilder<T> extends StreamBuilderBase<T, AsyncSnapshot<T>> {
/// will thus receive a timing-dependent sub-sequence of the snapshots that /// will thus receive a timing-dependent sub-sequence of the snapshots that
/// represent the interaction with the future. /// represent the interaction with the future.
/// ///
/// For a future that completes successfully with data, the [builder] may /// For a future that completes successfully with data, assuming [initialData]
/// be called with either both or only the latter of the following snapshots: /// is null, the [builder] will be called with either both or only the latter of
/// the following snapshots:
/// ///
/// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, null)` /// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, null)`
/// * `new AsyncSnapshot<String>.withData(ConnectionState.done, 'some data')` /// * `new AsyncSnapshot<String>.withData(ConnectionState.done, 'some data')`
/// ///
/// For a future completing with an error, the [builder] may be called with /// If that same future instead completed with an error, the [builder] would be
/// either both or only the latter of: /// called with either both or only the latter of:
/// ///
/// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, null)` /// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, null)`
/// * `new AsyncSnapshot<String>.withError(ConnectionState.done, 'some error')` /// * `new AsyncSnapshot<String>.withError(ConnectionState.done, 'some error')`
...@@ -414,11 +443,11 @@ class StreamBuilder<T> extends StreamBuilderBase<T, AsyncSnapshot<T>> { ...@@ -414,11 +443,11 @@ class StreamBuilder<T> extends StreamBuilderBase<T, AsyncSnapshot<T>> {
/// old future has already completed successfully with data as above, changing /// old future has already completed successfully with data as above, changing
/// configuration to a new future results in snapshot pairs of the form: /// configuration to a new future results in snapshot pairs of the form:
/// ///
/// * `new AsyncSnapshot<String>.withData(ConnectionState.none, 'some data')` /// * `new AsyncSnapshot<String>.withData(ConnectionState.none, 'data of first future')`
/// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, 'some data')` /// * `new AsyncSnapshot<String>.withData(ConnectionState.waiting, 'data of second future')`
/// ///
/// In general, the latter will be produced only when the new future is /// In general, the latter will be produced only when the new future is
/// non-null. The former only when the old future is non-null. /// non-null, and the former only when the old future is non-null.
/// ///
/// A [FutureBuilder] behaves identically to a [StreamBuilder] configured with /// A [FutureBuilder] behaves identically to a [StreamBuilder] configured with
/// `future?.asStream()`, except that snapshots with `ConnectionState.active` /// `future?.asStream()`, except that snapshots with `ConnectionState.active`
...@@ -461,12 +490,40 @@ class FutureBuilder<T> extends StatefulWidget { ...@@ -461,12 +490,40 @@ class FutureBuilder<T> extends StatefulWidget {
/// The asynchronous computation to which this builder is currently connected, /// The asynchronous computation to which this builder is currently connected,
/// possibly null. /// possibly null.
///
/// If no future has yet completed, including in the case where [future] is
/// null, the data provided to the [builder] will be set to [initialData].
final Future<T> future; final Future<T> future;
/// The build strategy currently used by this builder. Cannot be null. /// The build strategy currently used by this builder.
///
/// The builder is provided with an [AsyncSnapshot] object whose
/// [AsyncSnapshot.connectionState] property will be one of the following
/// values:
///
/// * [ConnectionState.none]: [future] is null. The [AsyncSnapshot.data] will
/// be set to [initialData], unless a future has previously completed, in
/// which case the previous result persists.
///
/// * [ConnectionState.waiting]: [future] is not null, but has not yet
/// completed. The [AsyncSnapshot.data] will be set to [initialData],
/// unless a future has previously completed, in which case the previous
/// result persists.
///
/// * [ConnectionState.done]: [future] is not null, and has completed. If the
/// future completed successfully, the [AsyncSnapshot.data] will be set to
/// the value to which the future completed. If it completed with an error,
/// [AsyncSnapshot.hasError] will be true and [AsyncSnapshot.error] will be
/// set to the error object.
final AsyncWidgetBuilder<T> builder; final AsyncWidgetBuilder<T> builder;
/// The data that will be used to create the initial snapshot. Null by default. /// The data that will be used to create the snapshots provided until a
/// non-null [future] has completed.
///
/// If the future completes with an error, the data in the [AsyncSnapshot]
/// provided to the [builder] will become null, regardless of [initialData].
/// (The error itself will be available in [AsyncSnapshot.error], and
/// [AsyncSnapshot.hasError] will be true.)
final T initialData; final T initialData;
@override @override
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment