0
0
Fluttermobile~20 mins

Async/await and Futures in Flutter - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Async Data Loader
This screen fetches a message from a simulated slow network call and displays it. It shows a loading spinner while waiting.
Target UI
-------------------------
| Async Data Loader     |
|-----------------------|
|                       |
|   [Loading spinner]    |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
-------------------------
Show a CircularProgressIndicator while waiting for data
Fetch data asynchronously using Future.delayed to simulate network delay
Display the fetched message once loaded
Use async/await syntax inside initState or a similar lifecycle method
Handle state updates properly to refresh UI
Starter Code
Flutter
import 'package:flutter/material.dart';

class AsyncDataLoader extends StatefulWidget {
  @override
  State<AsyncDataLoader> createState() => _AsyncDataLoaderState();
}

class _AsyncDataLoaderState extends State<AsyncDataLoader> {
  String? _message;

  @override
  void initState() {
    super.initState();
    // TODO: Call async function to load data here
  }

  Future<String> fetchMessage() async {
    // Simulate network delay
    await Future.delayed(Duration(seconds: 3));
    return 'Hello from async!';
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Async Data Loader')),
      body: Center(
        child: _message == null
            ? CircularProgressIndicator()
            : Text(_message!, style: TextStyle(fontSize: 24)),
      ),
    );
  }
}
Task 1
Task 2
Solution
Flutter
import 'package:flutter/material.dart';

class AsyncDataLoader extends StatefulWidget {
  @override
  State<AsyncDataLoader> createState() => _AsyncDataLoaderState();
}

class _AsyncDataLoaderState extends State<AsyncDataLoader> {
  String? _message;

  @override
  void initState() {
    super.initState();
    loadData();
  }

  Future<void> loadData() async {
    String msg = await fetchMessage();
    setState(() {
      _message = msg;
    });
  }

  Future<String> fetchMessage() async {
    await Future.delayed(Duration(seconds: 3));
    return 'Hello from async!';
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Async Data Loader')),
      body: Center(
        child: _message == null
            ? CircularProgressIndicator()
            : Text(_message!, style: TextStyle(fontSize: 24)),
      ),
    );
  }
}

We created a separate async method loadData called from initState. Inside it, we await the fetchMessage Future that simulates a 3-second delay. Once the message is ready, we call setState to update the UI with the new message. Until then, a loading spinner shows. This pattern lets the UI stay responsive and updates automatically when data arrives.

Final Result
Completed Screen
-------------------------
| Async Data Loader     |
|-----------------------|
|                       |
|   Hello from async!    |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
-------------------------
When the screen opens, a spinner shows for 3 seconds
After 3 seconds, the spinner disappears and the message 'Hello from async!' appears
Stretch Goal
Add a Refresh button in the AppBar that reloads the message when tapped
💡 Hint
Add an IconButton in AppBar actions that calls loadData() again to refresh