0
0
Fluttermobile~20 mins

Dio package for advanced HTTP in Flutter - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Advanced HTTP with Dio
This screen demonstrates advanced HTTP requests using the Dio package in Flutter. It fetches data from a public API, shows loading and error states, and allows retrying the request.
Target UI
┌───────────────────────────────┐
│ Advanced HTTP with Dio         │
├───────────────────────────────┤
│ [Fetch Data]                  │
│                               │
│ Status: Idle                  │
│                               │
│ Response:                    │
│ <empty>                      │
└───────────────────────────────┘
Add a button labeled 'Fetch Data' that triggers an HTTP GET request using Dio.
Show a loading indicator while the request is in progress.
Display the status text: 'Idle', 'Loading...', 'Success', or 'Error'.
Show the fetched JSON response in a scrollable Text widget.
Handle errors gracefully and allow retrying by pressing the button again.
Use Dio interceptors to log request and response info to the console.
Starter Code
Flutter
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';

class AdvancedHttpScreen extends StatefulWidget {
  @override
  State<AdvancedHttpScreen> createState() => _AdvancedHttpScreenState();
}

class _AdvancedHttpScreenState extends State<AdvancedHttpScreen> {
  final Dio dio = Dio();
  String status = 'Idle';
  String responseText = '';

  @override
  void initState() {
    super.initState();
    // TODO: Add Dio interceptors here
  }

  Future<void> fetchData() async {
    setState(() {
      status = 'Loading...';
      responseText = '';
    });
    try {
      // TODO: Make GET request to https://jsonplaceholder.typicode.com/posts/1
      // TODO: Update status and responseText on success
    } catch (e) {
      // TODO: Update status and responseText on error
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Advanced HTTP with Dio')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            ElevatedButton(
              onPressed: fetchData,
              child: Text('Fetch Data'),
            ),
            SizedBox(height: 20),
            Text('Status: $status'),
            SizedBox(height: 20),
            Expanded(
              child: SingleChildScrollView(
                child: Text(responseText),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
Task 1
Task 2
Task 3
Solution
Flutter
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';

class AdvancedHttpScreen extends StatefulWidget {
  @override
  State<AdvancedHttpScreen> createState() => _AdvancedHttpScreenState();
}

class _AdvancedHttpScreenState extends State<AdvancedHttpScreen> {
  final Dio dio = Dio();
  String status = 'Idle';
  String responseText = '';

  @override
  void initState() {
    super.initState();
    dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        print('Request: ${options.method} ${options.uri}');
        return handler.next(options);
      },
      onResponse: (response, handler) {
        print('Response: ${response.statusCode} ${response.data}');
        return handler.next(response);
      },
      onError: (DioError e, handler) {
        print('Error: ${e.message}');
        return handler.next(e);
      },
    ));
  }

  Future<void> fetchData() async {
    setState(() {
      status = 'Loading...';
      responseText = '';
    });
    try {
      final response = await dio.get('https://jsonplaceholder.typicode.com/posts/1');
      setState(() {
        status = 'Success';
        responseText = response.data.toString();
      });
    } catch (e) {
      setState(() {
        status = 'Error';
        responseText = e.toString();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Advanced HTTP with Dio')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            ElevatedButton(
              onPressed: fetchData,
              child: Text('Fetch Data'),
            ),
            SizedBox(height: 20),
            Text('Status: $status'),
            SizedBox(height: 20),
            Expanded(
              child: SingleChildScrollView(
                child: Text(responseText),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

We added Dio interceptors in initState to print request, response, and error details to the console. This helps us see what is happening behind the scenes.

The fetchData method uses Dio to make a GET request to a sample API. It updates the UI state to show loading, success, or error messages. The response data is shown as a string in a scrollable area.

This approach teaches how to handle advanced HTTP features like interceptors and error handling with Dio in Flutter.

Final Result
Completed Screen
┌───────────────────────────────┐
│ Advanced HTTP with Dio         │
├───────────────────────────────┤
│ [Fetch Data]                  │
│                               │
│ Status: Success               │
│                               │
│ Response:                    │
│ {                           │
│   "userId": 1,             │
│   "id": 1,                 │
│   "title": "...",        │
│   "body": "..."          │
│ }                           │
└───────────────────────────────┘
User taps 'Fetch Data' button.
Status text changes to 'Loading...'.
After successful fetch, status changes to 'Success' and JSON response is displayed.
If an error occurs, status changes to 'Error' and error message is shown.
Console logs show request and response details due to interceptors.
Stretch Goal
Add a retry button that appears only when the status is 'Error' to allow retrying the fetch.
💡 Hint
Use a conditional widget to show the retry button only on error, and call fetchData again when pressed.