Consume Data From API on Flutter Using DIO Package (1)
Tags: flutter, api, tutorial
Published: 2022-08-25 08:24:00

#Intro
For Mobile App developer consuming data from API is one of skill set that you must have. Flutter it self have many package to help developer consuming data from API.

#DIO
[DIO](https://pub.dev/packages/dio) is a popular package for retrive data from API on flutter, it's powefull and easy to use.

#GET Example
For example we would using [reqres.in](https://reqres.in) API to perform GET, POST and PUT

First we should make a data model, this is to store the data from API before we consume it with flutter.
You can make data model based on response data from API, here the response data from method GET reqres.in :
[GET:https://reqres.in/api/users?page=2](https://reqres.in/api/users?page=2)

```
class UserModel {
// this is the data from json response,
// each type data based on success json response
  int? page;
  int? perPage;
  int? total;
  int? totalPages;
  List<Data>? data;

// this is constructor
  UserModel({
    this.page,
    this.perPage,
    this.total,
    this.totalPages,
    this.data,
  });

// this is function to store data base on key-value response
  UserModel.fromJson(Map<String, dynamic> json) {
    page = json['page'];
    perPage = json['per_page'];
    total = json['total'];
    totalPages = json['total_pages'];
    data = json['data'] == null
        ? []
        : (json['data'] as List).map((e) => Data.fromJson(e)).toList();
// on this data we should mapping each response from List to 'class Data'
  }
}

// this class for store data from each response on List
class Data {
  int? id;
  String? email;
  String? firstName;
  String? lastName;
  String? avatar;

  Data({
    this.id,
    this.email,
    this.firstName,
    this.lastName,
    this.avatar,
  });

  Data.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    email = json['email'];
    firstName = json['first_name'];
    lastName = json['last_name'];
    avatar = json['avatar'];
  }
}
```
then we would make function to Get API with DIO.
Using GET method on DIO is easy, we just need to declare DIO package on a class then make a function to use method GET and passing the URL.

```
class ApiServices {
  Dio dio = Dio();

  Future<Map<String, dynamic>> getUser() async {
    const String url = 'https://reqres.in/api/users?page=2';
    try {
      Response response = await dio.get(url);
      return response.data;
    } on DioError catch (error, trace) {
      print('DIO error : $error, on : $trace');
      return error.response!.data;
    }
  }
}
```
Explanation:

`Future<Map<String, dynamic>> getUser() async {`

on this code, we use **Future** Type data because Dart only allow _asyncronous_ on **Future** type data function. Then we use Type data **Map** of **String**, and **dynamic** because the response from GET is still array of json, we need to mapping it later.

Then we make another function to cast Map of String, dynamic to List of DataModel:

```
Future<List<DataModel>> userServices() async {
    List<DataModel> userList = [];
    var response = await getUser();
    if (response.containsKey('data') && response['data'] is List) {
      userList =
          (response['data'] as List).map((e) => DataModel.fromJson(e)).toList();
    }
    return userList;
  }
```
Explanation:

`Future<List<DataModel>> userServices() async {`

The return data from **getUser** is **Map** of json data, we should convert it to **List** of **DataModel** before we consume it on Flutter.

`if (response.containsKey('data') && response['data'] is List) {`

Because we just want to consume array of 'data' we should ensure that the response has it and then we mapping it to DataModel.

`userList =
          (response['data'] as List).map((e) => DataModel.fromJson(e)).toList();`

And then we have **List** of **DataModel**, we can consume it with **ListView.builder()** on Flutter.

### Common DIO GET Method
Beside of 'path' on dio.get() there another parameter on method get() you can use:
`queryParameters:` to give param to API,
`options:` this required **Options()** and have many function like setting header etc.