Here’s a complete, easy-to-understand example of using Dio interceptors in Flutter to handle logging, authentication tokens, and errors 👇
🚀 Step-by-Step Example: Dio Interceptors in Flutter
🧩 Step 1: Add Dependencies
In your pubspec.yaml, add Dio:
dependencies:
dio: ^5.4.0
Then run:
flutter pub get
🧠 Step 2: Create a Dio Client with Interceptors
Create a file lib/core/network/api_client.dart:
import 'package:dio/dio.dart';
class ApiClient {
static final ApiClient _instance = ApiClient._internal();
factory ApiClient() => _instance;
late Dio dio;
ApiClient._internal() {
dio = Dio(
BaseOptions(
baseUrl: 'https://dummyjson.com', // example API
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 10),
headers: {
'Content-Type': 'application/json',
},
),
);
// Add interceptors
dio.interceptors.addAll([
LogInterceptor(
request: true,
requestBody: true,
responseBody: true,
responseHeader: false,
error: true,
),
AppInterceptors(dio),
]);
}
}
🧰 Step 3: Create a Custom Interceptor Class
Create lib/core/network/app_interceptor.dart:
import 'package:dio/dio.dart';
class AppInterceptors extends Interceptor {
final Dio dio;
AppInterceptors(this.dio);
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
// Example: Add authentication token to headers
const token = "dummy_auth_token";
options.headers["Authorization"] = "Bearer $token";
print('➡️ Request[${options.method}] => PATH: ${options.path}');
return handler.next(options);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
print('✅ Response[${response.statusCode}] => PATH: ${response.requestOptions.path}');
return handler.next(response);
}
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
print('❌ Error[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
// Example: Refresh token or show error
if (err.response?.statusCode == 401) {
// handle unauthorized error (refresh token logic here)
print("Token expired — refreshing...");
}
return handler.next(err);
}
}
🧪 Step 4: Use the API Client Anywhere
Example: lib/repository/user_repository.dart
import 'package:dio/dio.dart';
import '../core/network/api_client.dart';
class UserRepository {
final _client = ApiClient().dio;
Future<void> fetchUsers() async {
try {
final response = await _client.get('/users');
print('Users fetched: ${response.data}');
} on DioException catch (e) {
print('Error fetching users: ${e.message}');
}
}
}
🖥 Step 5: Call It in Your UI
import 'package:flutter/material.dart';
import 'repository/user_repository.dart';
class HomePage extends StatelessWidget {
final userRepo = UserRepository();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Dio Interceptor Example")),
body: Center(
child: ElevatedButton(
onPressed: () => userRepo.fetchUsers(),
child: Text("Fetch Users"),
),
),
);
}
}
✅ Output Example (in Console)
➡️ Request[GET] => PATH: /users
✅ Response[200] => PATH: /users
Users fetched: {users: [...], total: 100, ...}
⚡ Summary
| Purpose | Method |
|---|---|
| Add token to headers | onRequest |
| Handle API response | onResponse |
| Manage errors & retries | onError |
| Log everything | LogInterceptor |
1 comment
[…] Dio interceptors in flutter example […]