Introduction
Dio is a powerful HTTP client for Dart that supports interceptors, global configuration, FormData, and cancellation. When combined with BLoC, it forms a robust network layer for your Flutter apps. This guide covers how to integrate Dio with BLoC using the repository pattern, manage interceptors for authentication and logging, cancel in‑flight requests, handle errors gracefully, and test your network logic.
Why Use Dio with BLoC?
- Interceptor Support – Add headers, handle tokens, log requests globally.
- Request Cancellation – Cancel ongoing requests (e.g., when user navigates away).
- FormData & File Uploads – Easy multipart file uploads with progress.
- Flexible Configuration – Base URL, timeouts, response interceptors.
- Error Handling – Convert Dio errors to domain‑specific exceptions.
Setting Up Dio
Add Dio and other dependencies to your pubspec.yaml:
Create a Dio client with base configuration. It's often provided as a singleton or through dependency injection.
Repository Pattern
The repository pattern separates data sources (network, cache) from business logic. Your BLoC interacts with the repository, which uses Dio to fetch data.
BLoC with Repository
The BLoC uses the repository to perform network operations and emits states. Use Equatable for state equality.
Handling Request Cancellation
Cancelling requests is important when users navigate away or when multiple requests race. Use CancelToken in Dio. In the BLoC, you can cancel requests on close or when a new request arrives (restartable pattern).
Advanced: Interceptors for Authentication
Dio interceptors can automatically refresh expired tokens. This example shows how to intercept 401 errors and retry after refreshing the token.
Testing BLoC with Mocked Dio
To test BLoCs that use Dio, you can mock the repository or use MockClient from http_mock_adapter (for Dio). Mocktail can be used to mock the repository.
Best Practices
- Use a single Dio instance – Share a configured Dio client via dependency injection (e.g., GetIt, Provider).
- Separate network logic with repositories – Keep BLoC clean and testable.
- Use CancelToken – Cancel requests when the BLoC is closed or when a new request overrides an old one.
- Handle errors early – Convert Dio exceptions to domain‑specific exceptions in the repository.
- Use interceptors for cross‑cutting concerns – Logging, authentication, token refresh.
- Test with mocks – Avoid real network calls in unit tests; mock the repository or use an adapter.
- Set timeouts – Prevent hanging requests with
connectTimeoutandreceiveTimeout.
Common Mistakes
- ❌ Not handling request cancellation – Leads to memory leaks and unnecessary processing.
✅ Cancel tokens in
closeand on new requests. - ❌ Creating multiple Dio instances – Overhead and loss of shared configuration. ✅ Use a singleton or service locator.
- ❌ Ignoring error types – Throwing raw DioException makes BLoC handling messy. ✅ Map to custom exceptions.
- ❌ Forgetting to set content‑type headers – May cause server errors.
✅ Set base headers in
BaseOptions. - ❌ Not handling 401 globally – Leads to scattered authentication logic. ✅ Use an interceptor for token refresh.
Conclusion
Dio is a feature‑rich HTTP client that pairs excellently with BLoC. By organizing your network layer with repositories, using interceptors for cross‑cutting concerns, and managing request cancellation, you can build a robust, maintainable, and testable API integration. Following the patterns in this guide will ensure your BLoC remains focused on state management while Dio handles the complexities of HTTP communication.