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