Pendahuluan
Setelah mengenali beberapa widget Flutter dalam hal membuat UI atau layout, maka pada seri kali ini, secara perlahan kita akan melangkah ketingkatan yang lebih menarik lagi, yakni menyelesaikan sebuah case. Sebagai pijakan awal, case yang akan diangkat adalah sebuah case sederhana dalam mengelola data pegawai atau dengan istilah kerennya adalah CRUD (Create, Read, Update & Delete).
Kasus ini akan kita tutup hanya pada batasan data pegawai saja dengan tujuan untuk mengenali bagaimana cara kerja Flutter dalam berinteraksi dengan API. Sehingga, ketika berinteraksi dengan case yang lebih kompleks, kita tidak bingung lagi cara kerjanya.
Skenario sederhananya adalah membuat aplikasi dengan 2 buah page, dimana page pertama menampilkan seluruh data dan page kedua yang berisi form input-an berfungsi untuk menambahkan data baru atau memperbaharui data yang sudah ada.
Baca Juga: Mengenal Widget Flutter #8: Membuat Carousel Slide Show Dengan List View & Page View
Menampilkan Data Pegawai
Bagian pertama yang akan kita kerjakan adalah fitur untuk menampilkan seluruh data pegawai, sebelum memulainya, buat project baru dengan command
flutter create dw_employee_crud
Sebagaimana kita ketahui, file pertama yang akan di-load Flutter adalah main.dart
, jadi buka file lib/main.dart
dan modifikasi menjadi.
import 'package:flutter/material.dart';
import './pages/employee.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Employee(),
);
}
}
Untuk meng-handle tampilan dari data pegawai, dimana kita akan menampilkan beberapa informasi, diantaranya, nama pegawa, gaji dan umur, maka buat file baru bernama employee.dart
di dalam folder lib/pages
dan tambahkan struktur berikut
import 'package:flutter/material.dart';
import '../models/employee_model.dart';
class Employee extends StatelessWidget {
//DUMMY DATA YANG AKAN DITAMPILKAN SEBELUM MELAKUKAN HIT KE API
//ADAPUN FORMAT DATANYA MENGIKUTI STRUKTU YANG SUDAH DITETAPKAN PADA EMPLOYEEMODEL
final data = [
EmployeeModel(
id: "1",
employeeName: "Tiger Nixon",
employeeSalary: "320800",
employeeAge: "61",
profileImage: "",
),
EmployeeModel(
id: "2",
employeeName: "Anugrah Sandi",
employeeSalary: "40000",
employeeAge: "25",
profileImage: "",
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('DW Employee CRUD'),
),
//ADAPUN UNTUK LOOPING DATA PEGAWAI, KITA GUNAKAN LISTVIEW BUILDER
//KARENA WIDGET INI SUDAH DILENGKAPI DENGAN FITUR SCROLLING
body: ListView.builder(
itemCount: data.length, //MENGHITUNG JUMLAH DATA YANG AKAN DITAMPILKAN
//LOOPING DATA
itemBuilder: (context, i) {
//KEMUDIAN TAMPILKAN DATA PEGAWAI BERDASARKAN INDEX YANG DISIMPAN DI DALAM VARIABLE I
return Card(
elevation: 8,
child: ListTile(
title: Text(
data[i].employeeName,
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
subtitle:
Text('Umur: ${data[i].employeeAge}'),
trailing:
Text("\$${data[i].employeeSalary}"),
),
);
},
),
);
}
}
Adapun untuk formatting struktur data yang diinginkan, buat file employee_model.dart
di dalam folder lib/models
dan tambahkan code berikut
class EmployeeModel {
String id;
String employeeName;
String employeeSalary;
String employeeAge;
String profileImage;
//BUAT CONSTRUCTOR AGAR KETIKA CLASS INI DILOAD, MAKA DATA YANG DIMINTA HARUS DIPASSING SESUAI TIPE DATA YANG DITETAPKAN
EmployeeModel({
this.id,
this.employeeName,
this.employeeSalary,
this.employeeAge,
this.profileImage
});
//FUNGSI INI UNTUK MENGUBAH FORMAT DATA DARI JSON KE FORMAT YANG SESUAI DENGAN EMPLOYEE MODEL
factory EmployeeModel.fromJson(Map<String, dynamic> json) => EmployeeModel(
id: json['id'],
employeeName: json['employee_name'],
employeeSalary: json['employee_salary'],
employeeAge: json['employee_age'],
profileImage: json['profile_image']
);
}
Lakukan uji coba dengan menjalankan aplikasi yang kita buat, dari VsCode, klik menu Debug > Start Debugging atau menekan tombol F5. Hasil yang akan diperoleh kurang lebih seperti tampilan berikut
HTTP Request to Get Data
Tiba saatnya kita melakukan request ke API yang akan diambil datanya dan untuk melakukannya, kita membutuhkan dua buah library yakni HTTP untuk meng-handle request data dan Provider sebagai state management.
Buka file pubspec.yaml
dan tambahkan dua line berikut tepat dibawah line cupertino_icons
provider: ^4.0.2
http: ^0.12.0+4
Kemudian save atau jalankan command flutter pub get
untuk mengunduh seluruh file dari kedua library tersebut. Kemudian buat file baru bernama employee_provider.dart
di dalam folder lib/providers
dan tambahkan code.
import 'package:dw_employee_crud/models/employee_model.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class EmployeeProvider extends ChangeNotifier {
//DEFINISIKAN PRIVATE VARIABLE DENGAN TYPE List dan VALUENYA MENGGUNAKAN FORMAT EMPLOYEEMODEL
//DEFAULTNYA KITA BUAT KOSONG
List<EmployeeModel> _data = [];
//KARENA PRIVATE VARIABLE TIDAK BISA DIAKSES OLEH CLASS/FILE LAINNYA, MAKA DIPERLUKAN GETTER YANG BISA DIAKSES SECARA PUBLIC, ADAPUN VALUENYA DIAMBIL DARI _DATA
List<EmployeeModel> get dataEmployee => _data;
//BUAT FUNGSI UNTUK MELAKUKAN REQUEST DATA KE SERVER / API
Future<List<EmployeeModel>> getEmployee() async {
final url = 'http://employee-crud-flutter.daengweb.id/index.php';
final response = await http.get(url); //LAKUKAN REQUEST DATA
//JIKA STATUSNYA BERHASIL ATAU = 200
if (response.statusCode == 200) {
//MAKA KITA FORMAT DATANYA MENJADI MAP DENGNA KEY STRING DAN VALUE DYNAMIC
final result = json.decode(response.body)['data'].cast<Map<String, dynamic>>();
//KEMUDIAN MAPPING DATANYA UNTUK KEMUDIAN DIUBAH FORMATNYA SESUAI DENGAN EMPLOYEEMODEL DAN DIPASSING KE DALAM VARIABLE _DATA
_data = result.map<EmployeeModel>((json) => EmployeeModel.fromJson(json)).toList();
return _data;
} else {
throw Exception();
}
}
}
Agar bisa menggunakan provider di atas, register terlebih dahulu dengan cara buka file lib/main.dart
dan modifikasi class MyApp()
menjadi.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => EmployeeProvider(),
)
],
child: MaterialApp(
home: Employee(),
),
);
}
}
Jangan lupa dengan file yang sama, import kedua bagian ini
import 'package:provider/provider.dart';
import 'package:dw_employee_crud/providers/employee_provider.dart';
Saatnya kita melakukan fetch ke API dan menggunakan data yang diterima untuk ditampilkan pada UI yang sudah kita buat. Buka file lib/pages/employee.dart
dan modifikasi code yang ada pada body
dari Scaffold menjadi.
//FITUR DIMANA KETIKA PAGE DITARIK DARI ATAS KE BAWAH, MAKA AKAN MEMICU FUNGSI UNTUK MENGAMBIL DATA KE API
body: RefreshIndicator(
//ADAPUN FUNGSI YANG DIJALANKAN ADALAH getEmployee() DARI EMPLOYEE_PROVIDER
onRefresh: () =>
Provider.of<EmployeeProvider>(context, listen: false).getEmployee(),
color: Colors.red,
child: Container(
margin: EdgeInsets.all(10),
//KETIKA PAGE INI DIAKSES MAKA AKAN MEMINTA DATA KE API
child: FutureBuilder(
//DENGAN MENJALANKAN FUNGSI YANG SAMA
future: Provider.of<EmployeeProvider>(context, listen: false)
.getEmployee(),
builder: (context, snapshot) {
//JIKA PROSES REQUEST MASIH BERLANGSUNG
if (snapshot.connectionState == ConnectionState.waiting) {
//MAKA KITA TAMPILKAN INDIKATOR LOADING
return Center(
child: CircularProgressIndicator(),
);
}
//SELAIN ITU KITA RENDER ATAU TAMPILKAN DATANYA
//ADAPUN UNTUK MENGAMBIL DATA DARI STATE DI PROVIDER
//MAKA KITA GUNAKAN CONSUMER
return Consumer<EmployeeProvider>(
builder: (context, data, _) {
//KEMUDIAN LOOPING DATANYA DENGNA LISTVIEW BUILDER
return ListView.builder(
//ADAPUN DATA YANG DIGUNAKAN ADALAH REAL DATA DARI GETTER dataEmployee
itemCount: data.dataEmployee.length,
itemBuilder: (context, i) {
return Card(
elevation: 8,
child: ListTile(
title: Text(
//DAN DATA YANG DITAMPILKAN JG DIAMBIL DARI GETTER DATAEMPLOYEE
//SESUAI INDEX YANG SEDANG DILOOPING
data.dataEmployee[i].employeeName,
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
subtitle:
Text('Umur: ${data.dataEmployee[i].employeeAge}'),
trailing:
Text("\$${data.dataEmployee[i].employeeSalary}"),
),
);
},
);
},
);
},
),
),
),
Simpan semua perubahan yang sudah dilakukan, kemudian reload dan hasil yang akan ditampilkan kurang lebih seperti gambar dibawah ini
Langkah terakhir sebagai penutup adalah membuat tombol untuk berpindah ke screen selanjutnya meskipun untuk saat ini belum ada aksi dari tombol tersebut. Masih dengan file yang sama, tambahkan code berikut di dalam Scaffold.
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.pink,
child: Text('+'),
onPressed: () {},
),
Baca Juga: Mengenal Widget Flutter #7: Navigation Aplikasi Pariwisata
Kesimpulan
Sepanjang artikel ini kita telah belajar bagaimana menggunakan List View Builder, berinteraksi dengan model, melakukan fetch ke API, menggunakan Provider sebagai state management dan lain sebagainya. Seri selanjutnya kita akan belajar bagaimana menambahkan data baru ke API terkait.
Adapun dokumentasi code dari artikel ini bisa dilihat di Github.
Comments