I was wondering when I should use the future builder. For example, if I want to make an http request and show the results in a list view, as soon as you open the view, should I have to use the future builder or just build a ListViewBuilder
like:
new ListView.builder( itemCount: _features.length, itemBuilder: (BuildContext context, int position) { ...stuff here... }
Moreover, if I don't want to build a list view but some more complex stuff like circular charts, should I have to use the future builder?
Hope it's clear enough!
Show a constructor and parameters of Streambuilder. That is the way to utilize FutureBuilder in Flutter. You need to make a Future and pass it as the future argument. The snapshots of the Future will be passed to the builder function, in which you can decide the format to be shown depending on the current snapshot.
AsyncSnapshot<T> class Null safety. Immutable representation of the most recent interaction with an asynchronous computation. See also: StreamBuilder, which builds itself based on a snapshot from interacting with a Stream. FutureBuilder, which builds itself based on a snapshot from interacting with a Future.
Snapshot is the result of the Future or Stream you are listening to in your FutureBuilder . Before interacting with the data being returned and using it in your builder, you have to access it first.
FutureBuilder
removes boilerplate code.
Let's say you want to fetch some data from the backend on page launch and show a loader until data comes.
Tasks for ListBuilder:
dataFromBackend
and isLoadingFlag
isLoadingFlag = true
, and based on this, show loader
.isLoadingFlag = false
(inside setState
obviously)if-else
in widget creation. If isLoadingFlag
is true
, show the loader
else show the data
. On failure, show error message.Tasks for FutureBuilder:
future
of Future BuilderconnectionState
, show message (loading
, active(streams)
, done
)data(snapshot.hasError)
, show viewPros of FutureBuilder
setState
FutureBuilder
will take care of updating the view on data arrival)Example:
FutureBuilder<String>( future: _fetchNetworkCall, // async work builder: (BuildContext context, AsyncSnapshot<String> snapshot) { switch (snapshot.connectionState) { case ConnectionState.waiting: return Text('Loading....'); default: if (snapshot.hasError) return Text('Error: ${snapshot.error}'); else return Text('Result: ${snapshot.data}'); } }, )
Performance impact:
I just looked into the FutureBuilder
code to understand the performance impact of using this.
StatefulWidget
whose state
variable is _snapshot
_snapshot = AsyncSnapshot<T>.withData(ConnectionState.none, widget.initialData);
future
which we send via the constructor and update the state
based on that.Example:
widget.future.then<void>((T data) { if (_activeCallbackIdentity == callbackIdentity) { setState(() { _snapshot = AsyncSnapshot<T>.withData(ConnectionState.done, data); }); } }, onError: (Object error) { if (_activeCallbackIdentity == callbackIdentity) { setState(() { _snapshot = AsyncSnapshot<T>.withError(ConnectionState.done, error); }); } });
So the FutureBuilder
is a wrapper/boilerplate of what we do typically, hence there should not be any performance impact.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With