# How to Use Dio Package for Networking in Flutter

## What is Dio?

Certainly! The **Dio** package is a powerful HTTP networking library for **Dart** and **Flutter**. It simplifies making network requests and handling responses. Here are some key features and examples of how to use Dio:

1. **Global Configuration and Interceptors**:
    
    * Dio allows you to set global configurations and interceptors for all requests. You can customise headers, timeouts, and other settings.
        
    * Example:
        
        ```dart
        import 'package:dio/dio.dart';
        final dio = Dio();
        ```
        
2. **Performing GET and POST Requests**:
    
    * You can easily make GET and POST requests:
        
        ```dart
        // GET request
        Response response = await dio.get('/demo?id=02&name=dio');
        print(response.data.toString());
        
        // POST request
        response = await dio.post('/demo', data: {'id': 02, 'name': 'dio'});
        ```
        
3. **Concurrent Requests**:
    
    * Dio supports making multiple concurrent requests:
        
        ```dart
        await Future.wait([dio.post('/info'), dio.get('/token')]);
        ```
        
4. **File Uploading and Downloading**:
    
    * You can upload files to the server using FormData:
        
        ```dart
        import 'package:dio/dio.dart';
        import 'dart:io'; // Needed for accessing files
        // Assuming you have a method in your API service (or elsewhere) named `uploadFile`
        // and a variable named `post` of type `Post` (or your model class name) containing the data
        // Assuming the 'filePath' property exists in your Post model class
        final formData = FormData.fromMap({
          'name': 'dio',
          'date': DateTime.now().toIso8601String(),
          'file': await MultipartFile.fromFile(post.filePath, filename: 'upload.txt'),
        });
        await ApiService.uploadFile('/info', formData); // Replace '/info' with your actual endpoint
        // Assuming you have a method in your service (or elsewhere) named `downloadFile`
        // and a variable named `downloadUrl` containing the download URL
        final directory = await getTemporaryDirectory();
        final savePath = '${directory.path}/downloaded_file.txt'; // Replace with desired filename
        await ApiService.downloadFile(downloadUrl, savePath);
        ```
        
        **Explanation:**
        
        * We've assumed you have a `Post` model class or a similar class that represents the data you want to upload along with the file.
            
        * We've further assumed that your `Post` model class has a property named `filePath` that stores the path to the file you want to upload. Adjust this placeholder if the property name is different.
            
        * We've assumed you have methods in your API service (or a similar class) named `uploadFile` and `downloadFile` for handling uploads and downloads, respectively. Replace these with your actual method names.
            
        
        **Additional Notes:**
        
        * Remember to replace placeholders like `/info` and `downloadUrl` with your actual server-side API endpoint URLs.
            
        * You'll need to modify the code to call these methods appropriately from your UI or other parts of your code.
            
        * If the structure of your code is significantly different, please provide the relevant code sections for further customisation.
            
5. **Listening to Upload Progress**:
    
    * You can listen to the progress of file uploads:
        
        ```dart
        await dio.post(
          'https://www.fluttercommunity.com/joflee/2/8.2.1/demo',
          data: {'jj': 'aa' * 11},
          onSendProgress: (int sent, int total) {
            print('$sent $total');
          },
        );
        ```
        
6. **Custom Adapters and Transformers**:
    
    * Dio allows you to create custom adapters and transformers for handling specific data formats.
        

---

## How to Do Networking Using the Dio Package in Flutter

Certainly! Let’s break down the process of making API calls, creating model classes, and parsing data using the **Dio** package in Flutter. I’ll provide a step-by-step guide along with code examples.

### Step 1: Set Up Your Flutter Project

Before we dive into working with APIs, make sure you have Flutter and Dart installed. If you haven’t already, follow the official Flutter installation guide. Create a new Flutter project using the following command:

```bash
flutter create api_example
```

### Step 2: Add the Dio Package

To make HTTP requests, add the **dio** package to your `pubspec.yaml` file:

```yaml
dependencies:
  flutter:
    sdk: flutter
  dio: ^5.4.3
```

Run `flutter pub get` to fetch the dependencies.

### Step 3: Create Model Classes

To parse the JSON data received from the API, create a model class. For example:

```dart
class Post {
  final int userId;
  final int id;
  final String title;
  final String body;
  Post({required this.userId, required this.id, required this.title, required this.body});
  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
      body: json['body'],
    );
  }
  Map<String, dynamic> toJson() => {
    'userId': userId,
    'id': id,
    'title': title,
    'body': body,
  };
}
```

### Step 4: API Calling

```dart
import 'package:dio/dio.dart';
import 'package:flutter_api_example/post.dart';  // Import Post model
class ApiService {
  static const String baseUrl = 'https://jsonplaceholder.typicode.com'; // Replace with your API endpoint
  static Future<Post> fetchPost(int postId) async {
    final dio = Dio();
    final response = await dio.get('$baseUrl/posts/$postId');
    if (response.statusCode == 200) {
      return Post.fromJson(response.data);
    } else {
      throw Exception('Failed to fetch post: ${response.statusCode}');
    }
  }
  static Future<void> createPost(Post post) async {
    final dio = Dio();
    final response = await dio.post('$baseUrl/posts', data: post.toJson());
    if (response.statusCode == 201) {
      print('Post created successfully!');
    } else {
      throw Exception('Failed to create post: ${response.statusCode}');
    }
  }
}
```

### Step 5: Fetch Data from an API and Display on Screen

Let’s create a simple Flutter app that fetches and displays data from a public API. Here’s an example:

```dart
import 'package:flutter/material.dart';
import 'package:flutter_api_example/api_service.dart';
import 'package:flutter_api_example/post.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'API Example',
      home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  Future<Post?> _post;
  String _errorMessage = '';
  @override
  void initState() {
    super.initState();
    _fetchData(); // Fetch data on app launch
  }
  Future<void> _fetchData() async {
    setState(() {
      _errorMessage = ''; // Clear any previous error messages
      _post = null;         // Reset the post state
    });
    try {
      final post = await ApiService.fetchPost(1); // Assuming post ID is 1
      setState(() {
        _post = post;
      });
    } on Exception catch (e) {
      setState(() {
        _errorMessage = e.toString();
      });
      print('Error: $e');
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('API Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            if (_post != null)
            Text('Title: ${_post.title}'),
            if (_post != null)
            Text('Body: ${_post.body}'),
            if (_errorMessage.isNotEmpty)
              Text(
                'Error: $_errorMessage',
                style: const TextStyle(color: Colors.red),
              ),
            ElevatedButton(
              onPressed: _fetchData,
              child: const Text('Fetch Post'),
            ),
                    ElevatedButton(
                      onPressed: () async {
                        // Example of posting data (replace with your data)
                        final post = Post(userId: 1, id: 2, title: 'New Post', body: 'Here is a new post');
                        await ApiService.createPost(post);
                      }
             )
          ],
        ),
      ),
    );
  }
}
```

In this example:

* We create a simple app with a button that triggers the `fetchData` function.
    
* The `fetchData` function makes a GET request to the JSONPlaceholder API.
    
* If the response status code is 200, we extract the title from the response and update the UI.
    
* If there’s an error, we handle it gracefully.
    

---

## Difference Between http and dio packages in Flutter

Certainly! Let’s compare the **http** package and the **Dio** package in Flutter for making API calls. Both packages serve the purpose of handling HTTP requests, but they have different features and use cases:

1. **http Package**:
    
    * **Advantages**:
        
        * **Simplicity**: The **http** package is straightforward and easy to use. It provides basic functionality for making HTTP requests.
            
        * **Lightweight**: It’s a lightweight library, making it suitable for small projects and simple use cases.
            
    * **Disadvantages**:
        
        * **Basic Functionality**: The **http** package only covers the essentials for making network requests. Additional features must be implemented independently.
            
        * **Error Handling**: You need to write custom error-handling functions.
            
    * **Use Case**:
        
        * Ideal for small projects where development speed is crucial.
            
2. **Dio Package**:
    
    * **Advantages**:
        
        * **Feature-Rich**: **Dio** is a powerful HTTP client for Dart. It offers a wide range of features beyond basic networking.
            
        * **Interceptors**: You can use interceptors for tasks like logging, caching, and modifying requests and responses.
            
        * **Global Configuration**: Customise global settings for all requests.
            
        * **FormData and File Downloading**: Supports file uploading and downloading.
            
        * **Timeouts**: Set timeouts for requests.
            
        * **Fast and Efficient**: Utilises asynchronous and parallel requests.
            
    * **Disadvantages**:
        
        * **Complexity**: Due to its extensive functionality, there’s a higher chance of encountering bugs.
            
    * **Use Case**:
        
        * Suitable for larger projects with long-term support.
            
        * When development speed is less critical, and you prioritise additional features and reliability.
            

* **http** is simple and lightweight, while **Dio** provides more advanced features.
    
* Choose **http** for small projects and quick development.
    
* Opt for **Dio** when you need additional functionality and long-term support.
    

Remember that the choice depends on your project’s size, complexity, and specific requirements. Happy coding! 🚀

> In conclusion, the Dio package is a robust and feature-rich HTTP client for Dart and Flutter, offering advanced capabilities like global configuration, interceptors, concurrent requests, and file handling. While the http package is suitable for smaller projects due to its simplicity and lightweight nature, Dio excels in larger, more complex applications that require extensive networking features and long-term support. By understanding the strengths and use cases of each package, developers can make informed decisions to best meet their project's needs. Happy coding! 🚀

%%[linkedinwidget]
