Using FutureBuilder to Create a Better Widget

Jimmy Ho
3 min readMar 11, 2018

--

(Last updated on 2018–03–18: CustomState example is updated.)

I’ve been using Flutter to develop an app for several months and the experience so far is very enjoyable. In the course I hit obstacles but at the end I always (almost) managed to solve them.

But there was one area that has been particularly difficult to me — Future.

More precisely, was how to integrate Future into the Widget codes.

Handling of Future is a big topic in Flutter, it is used everywhere: from calling async API that is located on a remote server, to just showing a simple dialog box that says “Hello”.

Let’s say inside the build method, you need to create a listview based on a JSON returned from Firebase’s Realtime Database, you may write something like the following:

However since the call to Firebase returns a Future, execution inside _getData() will keep going and very likely you will get null returned at the bottom, until the “.then” callback is invoked later.

How about using the “await” keyword when calling Firebase?

It won’t be possible as _getData() is not marked as an async method. Ok why not put the async clause as well?

No way, for async method the return value must be a Future of something, you won’t get your problem solved.

Of course you may put certain widget level static variables here and there and calling setState() for rebuilding the widget whenever the remote data is returned, but it will turn messy very quickly and your widget will be nothing but chaos…

So any better way to handle this? Thanks god we have FutureBuilder.

I leave the detail explanation to the official documentation, put it simple a FutureBuilder is a widget that returns another widget based on the Future’s execution result. It serves as a bridge between Futures and the widget’s UI.

For the above example, with FutureBuilder the build method can become something as follow:

The master build method now is depending on the call result on FirebaseDatabase, if data comes back it will call _getData() and build a list of actual widgets, if no data is returned yet a CircularProgressIndicator will be shown instead, the flow of execution is much cleaner now!

I wish the official Flutter documentation would had more coverage on this use case so I would not had scratched off lots of hairs (which already not much left on my head)…

With the capability of FutureBuilder I even made an abstract class that enforces the pattern of “loading futures ->building widget” :

Using this base class, every time when building a widget you can put all your loading and validation logic inside the loadWidget() method. Since it is marked as “async” you can make any remote calls with “await”, make sure you got everything ready before entering the main widget building logic, and before the Future is done the widget will show a CircularProgressIndicator. Nevertheless instead of “build” the custom building logic needs to be placed inside another method, which is called “customBuild” here.

Thanks for reading and I believe somebody can provide a more elegant solution than mine, happy Fluttering!

--

--