Pada tutorial series Flutter kali ini, Konsep Koding akan berbagi tutorial Flutter Bahasa Indonesia mengenai cara get api atau consume API menggunakan Dio, Dio adalah salah satu library atau package di Flutter untuk consume API, Dio memiliki banyak kelebihan. 



Tentang Dio Flutter

Klien Http yang kuat untuk Dart, yang mendukung Interceptors, konfigurasi Global, FormData, Pembatalan Permintaan, Pengunduhan file, Timeout, dll.

API untuk Project

Disini kita akan menggunakan api open dari https://reqres.in/api/users?page yang JSON response nya seperti di bawah ini :




Memulai Project dan Koding

1. Pertama tambahkan package Dio dan GetX di pubspec.yaml

dependencies:

  flutter:

    sdk: flutter


# versions available, run `flutter pub outdated`.

dependencies:

  flutter:

    sdk: flutter


  # The following adds the Cupertino Icons font to your application.

  # Use with the CupertinoIcons class for iOS style icons.

  cupertino_icons:

    ^1.0.2

  # Add this 3 libs

  dio: ^4.0.6

  get: ^4.6.5

  shimmer:

 

2.  Tambahkan dan ubah file di bawah ini lib folder :



lib/account/account.controller.dart

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart' hide Response;
import 'package:resep/models/account.model.dart';
import 'package:resep/services/account.repository.dart';
import 'package:resep/services/dio.helper.dart';
class AccountController extends GetxController {
var isLoading = true.obs;
var isError = false.obs;
var errmsg = "".obs;
var acountData = <UserModel>[].obs;
Dio dio = Dio();
@override
void onInit() {
// TODO: implement onInit
getUser();
super.onInit();
}
@override
void onReady() {
super.onReady();
}
@override
void onClose() {
super.onClose();
}
Future<List<UserModel>> getUser() async {
isLoading(true);
try {
final result = await ApiClient().getData(ApiConst.path);
final List data = result["data"];
isLoading(false);
isError(false);
acountData.value = data.map((e) => UserModel.fromMap(e)).toList();
return acountData;
} catch (e) {
isLoading(false);
isError(true);
errmsg(e.toString());
throw Exception(e);
}
}
showToast(fName, lName, context) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("${fName} ${lName}"),
));
}
}


lib/account/account.dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:resep/account/account.controller.dart';
import 'package:shimmer/shimmer.dart';
class AccountScreen extends StatelessWidget {
const AccountScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final AccountController productController = Get.put(AccountController());
return Scaffold(
appBar: AppBar(title: const Text("Konsep Koding GetX and Dio")),
body: Container(
alignment: Alignment.topCenter,
padding: EdgeInsets.all(20),
child: Obx(() {
if (productController.isLoading.value)
return Shimmer.fromColors(
baseColor: Colors.grey[400]!,
highlightColor: Colors.grey[300]!,
child: ListView.builder(
shrinkWrap: true,
itemCount: 5,
itemBuilder: (context, index) => Container(
margin: const EdgeInsets.symmetric(
vertical: 10, horizontal: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
),
height: 100,
width: 200,
),
));
else if (productController.isError.value)
return Text(
"Error: ${productController.errmsg.value.capitalize}");
else //if loading == true, show progress indicator
// ignore: curly_braces_in_flow_control_structures
return Container(
//if there is any error, show error message
child: Column(
//if everything fine, show the JSON as widget
children:
productController.acountData.value.map<Widget>((user) {
return Card(
child: ListTile(
onTap: () {
productController.showToast(
user.firstName, user.lastName, context);
},
leading: CircleAvatar(
backgroundImage: NetworkImage(user.avatar),
),
title: Text(user.firstName),
subtitle: Text(user.email),
),
);
}).toList(),
));
})));
}
}
view raw account.dart hosted with ❤ by GitHub


lib/models/account.model.dart

import 'dart:convert';
List<UserModel> userModelFromMap(String str) =>
List<UserModel>.from(json.decode(str).map((x) => UserModel.fromMap(x)));
String userModelToMap(List<UserModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toMap())));
class UserModel {
UserModel({
required this.id,
required this.email,
required this.firstName,
required this.lastName,
required this.avatar,
});
int id;
String email;
String firstName;
String lastName;
String avatar;
factory UserModel.fromMap(Map<String, dynamic> json) => UserModel(
id: json["id"] == null ? null : json["id"],
email: json["email"] == null ? null : json["email"],
firstName: json["first_name"] == null ? null : json["first_name"],
lastName: json["last_name"] == null ? null : json["last_name"],
avatar: json["avatar"] == null ? null : json["avatar"],
);
Map<String, dynamic> toMap() => {
"id": id == null ? null : id,
"email": email == null ? null : email,
"first_name": firstName == null ? null : firstName,
"last_name": lastName == null ? null : lastName,
"avatar": avatar == null ? null : avatar,
};
}

lib/services/account.repository.dart


import 'package:dio/dio.dart';
import 'package:resep/services/dio.helper.dart';
class ApiClient {
Future getData(String path) async {
try {
final resonse =
await Dio(BaseOptions(baseUrl: ApiConst.baseUrl)).get(path);
return resonse.data;
} on DioError catch (e) {
throw Exception(e.message);
}
}
}

lib/services/dio.helper.dart


class ApiConst {
ApiConst._();
static const String baseUrl = "https://reqres.in/api/";
static const String path = "users?page";
}
view raw dio.helper.dart hosted with ❤ by GitHub

Dan ubah 

lib/main.dart


import 'package:flutter/material.dart';
import 'package:resep/account/account.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.green,
),
home: const AccountScreen(),
);
}
}
view raw main.dart hosted with ❤ by GitHub

Kemudian run project flutter run maka hasilnya akan seperti di bawah ini:








Penjelasan :

lib/account/account.controller.dart adalah logic yang untuk semua aplikasi kita entah itu untuk hit api, menampilkan alert dan logic lainnya

lib/account/account.dart adalah main UI untuk menampilkan hasil dari API yang di binding dengan GetX dari controller

lib/models/account.model.dart adalah untuk mendeklarasi json response dari server

lib/services/account.repository.dart adalah logic untuk repository dari server yang kemudian dikirim ke controller untuk diolah dan dikirimkan ke UI

lib/services/dio.helper.dart adalah layaknya constant untuk api url dsb disini saya buat khusus untuk helper api kita pisah dengan constant lain jadi khusus untuk URL dan API saja.


Source Project

Kamu bisa mendonwload full project tadi disini dan bisa kamu langsung coba: Source Code

Sekian Tutorial Flutter Get API dengan Dio, GetX dan Shimmer Yang Baik semoga tutorial dari Konsep Koding ini dapat bermanfaat dan membantu kamu yang sedang mempelajari Futter.

Baca Tutorial Flutter Dart KonsepKoding Lainnya:
#28 Tutorial HTTP Request Flutter Get API
#29 Tutorial Membuat UI Login Animasi Keren Flutter