Understanding the await Function in Flutter

What is the await Function?

by Ans Ali

In Dart, the programming language used by Flutter, await is a keyword that allows you to pause the execution of an async function until a Future completes. A Future is an object representing the eventual result of an asynchronous operation. By using await function, you can write asynchronous code that looks and behaves like synchronous code, improving readability and maintainability.

Asynchronous programming is a fundamental aspect of modern app development, enabling developers to write non-blocking code that can handle multiple tasks simultaneously. In Flutter, the await keyword plays a crucial role in making asynchronous programming easier.

How the await Function Works

When you use the await function, the following happens:

Pausing Execution

The function execution is paused at the await expression until the Future completes.

Continuing Execution

Once the Future completes (either successfully with a result or with an error), the execution resumes, and you can use the result of the Future.

Here’s a basic syntax structure:

Future<void> myAsyncFunction() async {
  var result = await someAsyncOperation();
  print(result);
}

Using the await Function in Flutter

Example 1: Fetching Data from an API

Let’s illustrate how to use the await function in a Flutter application by fetching data from a REST API.

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Await Example')),
      body: Center(
        child: FutureBuilder<List<Post>>(
          future: fetchPosts(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return CircularProgressIndicator();
            } else if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
              return Text('No Posts Available');
            }
            return ListView.builder(
              itemCount: snapshot.data!.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(snapshot.data![index].title),
                );
              },
            );
          },
        ),
      ),
    );
  }
  Future<List<Post>> fetchPosts() async {
    final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
    if (response.statusCode == 200) {
      List<dynamic> jsonResponse = json.decode(response.body);
      return jsonResponse.map((post) => Post.fromJson(post)).toList();
    } else {
      throw Exception('Failed to load posts');
    }
  }
}
class Post {
  final int id;
  final String title;
  Post({required this.id, required this.title});
  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      id: json['id'],
      title: json['title'],
    );
  }
}
Example 2: Simulating a Delay

You can also use the await function with Future.delayed simulating asynchronous behaviour, like loading data or performing a task after a delay.

Future<void> simulateLoading() async {
  print('Loading data...');
  await Future.delayed(Duration(seconds: 2));
  print('Data loaded!');
}
void main() {
  runApp(MyApp());
  simulateLoading();
}

Error Handling with the await Function

When using the await function, it's essential to handle potential errors. You can use try-catch blocks to manage exceptions that may arise during asynchronous operations.

Future<void> fetchData() async {
  try {
    var data = await fetchPosts();
    print('Fetched data: $data');
  } catch (e) {
    print('Error occurred: $e');
  }
}

Best Practices for Using the await Function

Use async Functions

Remember that await can only be used inside functions marked with the async keyword.

Avoid Blocking the Main Thread

Ensure that you’re using await on tasks that need to be asynchronous to avoid blocking the main thread, which can lead to a poor user experience.

Error Handling

Always implement error handling when using await to gracefully manage any exceptions.

Wrap-Up

The await keyword in Flutter simplifies asynchronous programming by allowing developers to write code that reads more like synchronous code. By using the await function with async functions, you can manage tasks such as fetching data from APIs, simulating delays, and more without complicating your code structure.

Enhance Your Flutter Skills

Stay tuned to our blog for more insights on Flutter development.

Flutter Build Modes Explained
Debug, Release & Profile