Tutorial 8: Flutter Model dan Komunikasi dengan Web Service
Pemrograman Berbasis Platform (CSGE602022) - diselenggarakan oleh Fakultas Ilmu Komputer, Universitas Indonesia, Semester Ganjil 2022/2023
Tujuan Pembelajaran
Setelah menyelesaikan tutorial ini, mahasiswa diharapkan untuk:
- Memahami struktur dan pembuatan model pada Flutter.
- Memahami cara mengambil, mengolah, dan menampilkan data dari web service.
Model pada Flutter
Pada tutorial kali ini, kita akan membuat sebuah pemanggilan web service hingga menampilkannya ke halaman Flutter yang kita buat. Akan tetapi sebelum melakukan pemanggilan web service, kita perlu mendefinisikan model yang kita gunakan ketika melakukan pemanggilan web service. Model pada Flutter menggunakan prinsip class seperti layaknya yang sudah dipelajari pada DDP2 bagian OOP.
Kode di bawah ini adalah contoh, tidak wajib diikuti, tetapi sangat disarankan dibaca karena konsepnya akan digunakan pada bagian-bagian selanjutnya.
Berikut merupakan contoh class pada Flutter.
class Mobil {
Mobil({
this.id,
this.brand,
this.model
this.color
});
int id;
String brand;
String model;
String color;
}
Catatan: Jika kamu mengalami error saat membuat class, tambahkan keyword required pada setiap parameter class pada bagian constructor.
Sampai saat ini, kita telah berhasil membuat class. Selanjutnya, kita akan menambahkan beberapa kode sehingga terbentuk sebuah model Mobil
. Mobil
ini merupakan suatu model yang merepresentasikan response dari pemanggilan web service.
Tambahkan import dart convert pada bagian paling atas file.
import 'dart:convert';
...
Pada class Mobil
, tambahkan kode berikut.
factory Mobil.fromJson(Map<String, dynamic> json) => Mobil(
id: json["id"],
brand: json["brand"],
model: json["model"],
color: json["color"],
);
Map<String, dynamic> toJson() => {
"id": id,
"brand": brand,
"model": model,
"color": color,
};
Tambahkan kode berikut di luar class Mobil
.
Mobil mobilFromJson(String str) => Mobil.fromJson(json.decode(str));
String mobilToJson(Mobil data) => json.encode(data.toJson());
Sehingga kode akhirnya akan seperti berikut untuk menampilkan satu objek Mobil
dari web service.
import 'dart:convert';
Mobil mobilFromJson(String str) => Mobil.fromJson(json.decode(str));
String mobilToJson(Mobil data) => json.encode(data.toJson());
class Mobil {
Mobil({
this.id,
this.brand,
this.model,
this.color,
});
int id;
String brand;
String model;
String color;
factory Mobil.fromJson(Map<String, dynamic> json) => Mobil(
id: json["id"],
brand: json["brand"],
model: json["model"],
color: json["color"],
);
Map<String, dynamic> toJson() => {
"id": id,
"brand": brand,
"model": model,
"color": color,
};
}
Penjelasan kode di atas adalah sebagai berikut.
Terdapat beberapa kode-kode tambahan seperti method toJson
dan fromJson
di dalam class Mobil
. Hal tersebut disebabkan ketika kita me-request suatu web service dengan method GET, umumnya kita mendapatkan hasil pemanggilan berupa JSON. Oleh karena itu, kita perlu melakukan konversi data dengan method fromJson
agar Flutter mengenali JSON tersebut sebagai objek class Mobil
. Selain itu, terdapat juga method toJson
yang akan digunakan ketika kita melakukan pengiriman data ke web service (seperti POST atau PUT).
Berikut adalah contoh respons dari web service dengan method GET yang dapat dikonversi ke class model Mobil tersebut.
{
"id": 1,
"brand": "Honda",
"model": "Civic",
"color": "Yellow"
}
Lalu, bagaimana jika respons dari web service berupa kumpulan objek JSON? Sebenarnya sama saja dengan kode di atas, hanya saja terdapat pengubahan pada method mobilFromJson
dan mobilToJson
.
Kodenya adalah sebagai berikut.
List<Mobil> mobilFromJson(String str) => List<Mobil>.from(json.decode(str).map((mobil) => Mobil.fromJson(mobil)));
String mobilToJson(List<Mobil> data) => json.encode(List<dynamic>.from(data.map((mobil) => mobil.toJson())));
Berikut adalah contoh respons dari web service dengan method GET yang dapat dikonversi ke model Mobil
tersebut.
[
{
"id": 1,
"brand": "Honda",
"model": "Civic",
"color": "Yellow"
},
{
"id": 2,
"brand": "Toyota",
"model": "Supra",
"color": "Red"
}
]
Fetch Data dari Web Service pada Flutter
Sebagai seorang developer, tentunya kita membutuhkan data untuk ditampilkan ke client. Hal ini mengharuskan kalian untuk mengetahui bagaimana cara untuk melakukan fetching data dari web service kemudian menampilkannya ke aplikasi yang telah kita buat sebelumnya.
Secara umum terdapat beberapa langkah ketika ingin menampilkan data dari web service lain ke aplikasi Flutter, yaitu:
Menambahkan dependency
http
ke proyek, dependency ini digunakan untuk bertukar data melalui HTTP request, seperti GET, POST, PUT, dan lain-lain.Membuat model sesuai dengan respons dari data yang berasal dari web service tersebut.
Membuat http request ke web service menggunakan dependency
http
.Mengkonversikan objek yang didapatkan dari web service ke model yang telah kita buat di langkah kedua.
Menampilkan data yang telah dikonversi ke aplikasi dengan
FutureBuilder
.
Selengkapnya dapat dibaca pada tautan berikut: https://docs.flutter.dev/cookbook/networking/fetch-data#5-display-the-data
Tutorial: Refactor File
Refaktorisasi kode (refactor code) adalah proses restrukturisasi kode program yang ada tanpa mengubah behavior program. Proses ini dilakukan untuk meningkatkan keterbacaan, mengurangi kompleksitas kode, dan memudahkan proses maintenance ke depannya.
Buka proyek yang sebelumnya telah dibuat pada tutorial sebelumnya dengan menggunakan IDE favoritmu.
Di dalam folder
lib
, buatlah dua folder baru dengan namamodel
danpage
.Pindahkan file selain
main.dart
ke dalam ke folderpage
.
Tutorial: Membuat Model Kustom
Dalam membuat model yang menyesuaikan dengan data JSON, kita dapat memanfaatkan website Quicktype dengan tahapan sebagai berikut.
Buka situs web https://jsonplaceholder.typicode.com/todos?_start=0&_limit=10 untuk mendapatkan data JSON.
Salinlah data JSON pada situs web sebelumnya, kemudian buka situs web Quicktype.
Pada situs web Quicktype, ubahlah setup name menjadi
ToDo
, source type menjadiJSON
, dan language menjadi Dart.Tempel data JSON yang telah disalin sebelumnya ke dalam textbox yang tersedia pada Quicktype.
Berikut adalah contoh hasilnya.
Klik pilihan
Copy Code
pada Quicktype.
Setelah mendapatkan kode model melalui Quicktype, buka kembali proyek Flutter dan lakukan langkah-langkah berikut.
Buatlah file baru pada folder
lib/model
dengan namato_do.dart
.Tempel kode yang telah disalin sebelumnya ke file
to_do.dart
.
Catatan: Jika kamu mengalami error saat membuat model, tambahkan keyword required pada setiap parameter model pada bagian constructor.
Tutorial: Menambahkan Dependensi HTTP
Untuk melakukan perintah HTTP request, kita membutuhkan package tambahan yakni package http.
Lakukan
flutter pub add http
pada terminal proyek Flutter untuk menambahkan packagehttp
.Pada file
android/app/src/main/AndroidManifest.xml
, tambahkan kode berikut untuk memperbolehkan akses Internet pada aplikasi Flutter yang sedang dibuat....
<application>
...
</application>
<!-- Required to fetch data from the Internet. -->
<uses-permission android:name="android.permission.INTERNET" />
...
Tutorial: Mengambil dan Mengolah Data dari Web Service
Buatlah file baru pada folder
lib/page
dengan namato_do_page.dart
.Pada file
to_do_page.dart
, tambahkan impor yang dibutuhkan. Ubahlah <APP_NAME> sesuai dengan nama proyek Flutter yang kalian buat.import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:<APP_NAME>/model/to_do.dart';
...Buatlah stateful widget dengan nama class
ToDoPage
. Contoh struktur stateful widget dapat dilihat pada tautan berikut.Lakukan pengambilan data dari URL https://jsonplaceholder.typicode.com/todos?_start=0&_limit=10 menggunakan metode
http.get
.class ToDoPage extends StatefulWidget {
const ToDoPage({Key? key}) : super(key: key);
@override
_ToDoPageState createState() => _ToDoPageState();
}
class _ToDoPageState extends State<ToDoPage> {
Future<List<ToDo>> fetchToDo() async {
var url = Uri.parse('https://jsonplaceholder.typicode.com/todos?_start=0&_limit=10');
var response = await http.get(
url,
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
},
);
// melakukan decode response menjadi bentuk json
var data = jsonDecode(utf8.decode(response.bodyBytes));
// melakukan konversi data json menjadi object ToDo
List<ToDo> listToDo = [];
for (var d in data) {
if (d != null) {
listToDo.add(ToDo.fromJson(d));
}
}
return listToDo;
}
...
}
Tutorial: Menampilkan Data dari Web Service
Pada file
main.dart
danform.dart
tambahkan kode berikut untuk menambahkan menu To Do pada drawer yang telah kita buat (letakkan di bawah menu ListTile form).ListTile(
title: const Text('To Do'),
onTap: () {
// Route menu ke halaman to do
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const ToDoPage()),
);
},
),Sehingga kodenya menjadi seperti ini:
...
ListTile(
title: const Text('Form'),
onTap: () {
// Route menu ke halaman form
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const MyFormPage()),
);
},
),
ListTile(
title: const Text('To Do'),
onTap: () {
// Route menu ke halaman to do
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const ToDoPage()),
);
},
),
...Pada bagian
Widget(BuildContext context)
, tambahkan kode berikut setelahreturn
.Scaffold(
appBar: AppBar(
title: const Text('To Do'),
),
drawer: Drawer(
child: Column(
children: [
// Menambahkan clickable menu
ListTile(
title: const Text('Counter'),
onTap: () {
// Route menu ke halaman utama
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const MyApp()),
);
},
),
ListTile(
title: const Text('Form'),
onTap: () {
// Route menu ke halaman form
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const MyFormPage()),
);
},
),
ListTile(
title: const Text('ToDo'),
onTap: () {
// Route menu ke halaman to do
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const ToDoPage()),
);
},
),
],
),
),
body: FutureBuilder(
future: fetchToDo(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return const Center(child: CircularProgressIndicator());
} else {
if (!snapshot.hasData) {
return Column(
children: const [
Text(
"Tidak ada to do list :(",
style: TextStyle(
color: Color(0xff59A5D8),
fontSize: 20),
),
SizedBox(height: 8),
],
);
} else {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (_, index)=> Container(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
padding: const EdgeInsets.all(20.0),
decoration: BoxDecoration(
color:Colors.white,
borderRadius: BorderRadius.circular(15.0),
boxShadow: const [
BoxShadow(
color: Colors.black,
blurRadius: 2.0
)
]
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${snapshot.data![index].title}",
style: const TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Text("${snapshot.data![index].completed}"),
],
),
)
);
}
}
}
)
);Restart aplikasi dengan menekan tombol
r
pada command line atau terminal di tempat kamu menjalankan Flutter. Hasilnya akan seperti gambar di bawah.
Akhir Kata
Selamat, kamu telah mempelajari mengenai model dan web service pada Flutter!
Jika kamu ingin mencoba tantangan, maka cobalah untuk menerapkan hal berikut pada tutorial ini.
- Lakukan refactor pada method
fetchToDo
ke file terpisah.
Referensi Tambahan
Kontributor
- Zuhal 'Alimul Hadi
- Sabyna Maharani
- Brandon Ivander
- Muhammad Athallah