Solve Async Callbacks with FutureBuilder!
Tags: flutter, beginners, android, codequality
Published: 2020-08-29 05:46:27

[Flutter](https://flutter.dev/) and [Dart](https://dart.dev/) are asynchronous in nature. Dart's [Future](https://api.dart.dev/stable/2.9.2/dart-async/Future-class.html) provides a very smooth experience when it comes to handling I/O without worrying about threads or deadlocks.

> A Future is used to represent a potential value, or error, that will be available at some time in the future. 

Receivers of a Future can register callbacks that handle the value or error once it is available.

![Future](https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi0.wp.com%2Fthinkdiff.net%2Fwp-content%2Fuploads%2F2019%2F08%2FFlutter-_-Dart-3.jpg%3Ffit%3D1200%252C675%26ssl%3D1&f=1&nofb=1)

---

# **Why FutureBuilder is required!**

Suppose you want to return a widget in the `build` method but the data required in the widget comes from an `async` function.

```bash
class MyWidget extends StatelessWidget {
  @override
  Widget build(context) {
    yourAsyncFetch().then((data) {
      return ...yourStuff(with the data);
    });
  }
}
```

Provided that the fetch could be an HTTP call, a call to SQLite or any call in general that returns a `Future`, this approach won't really work out.

Because a Widget's `build` method is **synchronous** and it won't wait while you fetch data.

<p align="center">
  <img src="https://media.giphy.com/media/2zdnl4CB3OygOHe1kX/giphy.gif" width="300" />

This is where **FutureBuilder** (`FutureBuilder<T>`) comes into the picture.

---

# **The Fix**

A `FutureBuilder` takes a Future as an argument, as well as a builder (A delegate called by the widget's build method). The builder will be called immediately, and again when our future resolves with either data or an error.

A `Future` must not be created during `build` when constructing the `FutureBuilder`. If the future is created at the same time as the `FutureBuilder`, then every time the `FutureBuilder`'s parent is rebuilt, the asynchronous task will be restarted.

An `AsyncSnapshot<T>` is simply a representation of that data/error state.

```bash
Future<String> yourAsyncFetch() => Future.delayed(Duration(seconds: 3), () => "Text coming after 3 seconds");

class MyWidget extends StatelessWidget {
  @override
  Widget build(context) {
    return FutureBuilder<String>(
      future: yourAsyncFetch(),
      builder: (context, AsyncSnapshot<String> snapshot) {
        if (snapshot.hasData) {
          return Text(snapshot.data); // Display the data from yourAsyncFetch() function after 3 seconds
        } else {
          return CircularProgressIndicator(); // Display a Circular Progress Indicator if the data is not fetched
        }
      }
    );
  }
}
```

**Voila! Problem Solved.**

---

<p align="center">
  <img src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fsi.wsj.net%2Fpublic%2Fresources%2Fimages%2FBN-TS039_fundpe_TOP_20170602140435.jpg&f=1&nofb=1" width="300" />

# **Effect on Performance**

FutureBuilder is just a `StatefulWidget` whose `state` is a **_snapshot**. It's initial state is `_snapshot = AsyncSnapshot<T>.withData(ConnectionState.none, widget.initialData);`

It subscribes to a future which we send and updates the state based on that.

```bash
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);
       });
    }
});
```

Thus the `FutureBuilder` is just a wrapper of what we normally do, so there is no impact on the performance.

---

![Thank You](https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.confidencecoach.org%2Fwp-content%2Fuploads%2F2019%2F03%2FWhite-Sticky-Note-With-Thank-You-Message-And-Red-Push-Pin-On-Yellow-Background-941674606_841x421.jpeg&f=1&nofb=1)

# Conclusion

That's all folks 👨‍🏫, Thank you for reading it till the end. I hope this helped you get a better idea of FutureBuilder and its real application out there. If I missed out anything do let me know in the comments and we can have a brainstorm session! 👨🏻‍💻

<p align="center">
![Flutter](https://pbs.twimg.com/profile_banners/1271743993026658305/1593020191/1500x500)

[Flutter Kolkata](https://twitter.com/flutterkolkata) is a group for people who wants to learn and explore Flutter Development. We invite both beginners as well as pro Dart accolades. Do join and get indulged with us on [our Discord](https://discord.gg/utqkRPV)

Don't forget to share these resources with someone who you think might need some help with FutureBuilder too. Peace out. ✌🏼