Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I use a FutureBuilder?

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!

like image 275
Little Monkey Avatar asked Aug 23 '18 09:08

Little Monkey


People also ask

How do you add a future builder in Flutter?

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.

What is Flutter AsyncSnapshot?

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.

What is snapshot Flutter?

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.


1 Answers

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:

  • Have two state variables, dataFromBackend and isLoadingFlag
  • On launch, set isLoadingFlag = true, and based on this, show loader.
  • Once data arrives, set data with what you get from backend and set isLoadingFlag = false (inside setState obviously)
  • We need to have a if-else in widget creation. If isLoadingFlag is true, show the loader else show the data. On failure, show error message.

Tasks for FutureBuilder:

  • Give the async task in future of Future Builder
  • Based on connectionState, show message (loading, active(streams), done)
  • Based on data(snapshot.hasError), show view

Pros of FutureBuilder

  • Does not use the two state variables and setState
  • Reactive programming (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.

  • FutureBuilder is just a StatefulWidget whose state variable is _snapshot
  • Initial state is _snapshot = AsyncSnapshot<T>.withData(ConnectionState.none, widget.initialData);
  • It is subscribing to 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.

like image 70
Dinesh Balasubramanian Avatar answered Sep 19 '22 02:09

Dinesh Balasubramanian