0
0
Fluttermobile~20 mins

Loading and error states in Flutter - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Data Fetch Screen
This screen fetches data from a fake source and shows loading and error states.
Target UI
-------------------------
| Data Fetch Screen      |
|-----------------------|
| [Loading spinner]      |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
-------------------------
Show a CircularProgressIndicator while loading data.
Show an error message with a Retry button if loading fails.
Show the fetched data text when loading succeeds.
Retry button triggers data fetch again.
Starter Code
Flutter
import 'package:flutter/material.dart';

class DataFetchScreen extends StatefulWidget {
  @override
  State<DataFetchScreen> createState() => _DataFetchScreenState();
}

class _DataFetchScreenState extends State<DataFetchScreen> {
  bool _isLoading = false;
  bool _hasError = false;
  String _data = '';

  void _fetchData() async {
    // TODO: Implement data fetching with loading and error states
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Data Fetch Screen')),
      body: Center(
        child: // TODO: Show loading spinner, error message with retry, or data text
      ),
    );
  }
}
Task 1
Task 2
Task 3
Task 4
Task 5
Task 6
Solution
Flutter
import 'package:flutter/material.dart';
import 'dart:math';

class DataFetchScreen extends StatefulWidget {
  @override
  State<DataFetchScreen> createState() => _DataFetchScreenState();
}

class _DataFetchScreenState extends State<DataFetchScreen> {
  bool _isLoading = false;
  bool _hasError = false;
  String _data = '';

  Future<void> _fetchData() async {
    setState(() {
      _isLoading = true;
      _hasError = false;
      _data = '';
    });

    await Future.delayed(Duration(seconds: 2));

    bool success = Random().nextBool();

    if (success) {
      setState(() {
        _isLoading = false;
        _data = 'Here is the fetched data!';
      });
    } else {
      setState(() {
        _isLoading = false;
        _hasError = true;
      });
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Data Fetch Screen')),
      body: Center(
        child: _isLoading
            ? CircularProgressIndicator()
            : _hasError
                ? Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Text('Failed to load data.', style: TextStyle(color: Colors.red, fontSize: 16)),
                      SizedBox(height: 12),
                      ElevatedButton(
                        onPressed: _fetchData,
                        child: Text('Retry'),
                      ),
                    ],
                  )
                : Text(_data, style: TextStyle(fontSize: 18)),
      ),
    );
  }
}

This screen uses a StatefulWidget to manage loading, error, and data states.

The _fetchData method simulates a network call with a 2-second delay. It randomly decides success or failure.

While loading, it shows a CircularProgressIndicator. If an error occurs, it shows a red error message and a Retry button. On success, it shows the fetched data text.

The Retry button calls _fetchData again to retry loading.

Final Result
Completed Screen
-------------------------
| Data Fetch Screen      |
|-----------------------|
|       (spinner)        |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
-------------------------

-- OR --

-------------------------
| Data Fetch Screen      |
|-----------------------|
| Failed to load data.   |
|                       |
|       [Retry]         |
|                       |
|                       |
|                       |
|                       |
|                       |
-------------------------

-- OR --

-------------------------
| Data Fetch Screen      |
|-----------------------|
| Here is the fetched    |
| data!                 |
|                       |
|                       |
|                       |
|                       |
|                       |
|                       |
-------------------------
When the screen opens, a spinner shows for 2 seconds.
After loading, either data text appears or error message with Retry button.
Tapping Retry repeats the loading process.
Stretch Goal
Add a pull-to-refresh gesture to reload the data.
💡 Hint
Wrap the body with a RefreshIndicator widget and call _fetchData on refresh.