Pendahuluan
Seri lanjutan dalam belajar CRUD dengan case aplikasi Data Pegawai, dimana pada seri kali ini kita membahas cara menambahkan data baru ke database melalui API yang sudah disediakan. Ada beberapa bagian yang akan kita pelajari, yakni cara melakukan HTTP request dengan method POST di Flutter, membuat loading indicator dan menampilkan snackbar sebagai alert notifikasi.
Batasan pembahasan kita pada materi ini hanya menyelesaikan proses menambahkan data baru, adapun proses lainnya seperti update dan delete data akan dibahas pada seri selanjutnya.
Baca Juga: Mengenal Widget Flutter #9: CRUD Data Pegawai Part 1
Membuat Form Input
Fitur kali ini yang akan dibuat adalah sebuah fitur untuk menambahkan data baru ke server melalui API yang telah disediakan. Tugas kita adalah membuat sebuah form input agar user bisa memasukkan data yang ingin ditambahkan. Buat file employee_add.dart
di dalam folder lib/pages
dan tambahkan struktur berikut.
import 'package:dw_employee_crud/pages/employee.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/employee_provider.dart';
class EmployeeAdd extends StatefulWidget {
@override
_EmployeeAddState createState() => _EmployeeAddState();
}
class _EmployeeAddState extends State<EmployeeAdd> {
//KOMENTAR-3: DEFINE VARIABLE
void submit(BuildContext context) {
//KOMENTAR-2 PROGRESS SIMPAN DATA
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: snackbarKey,
appBar: AppBar(
title: Text('Add Employee'),
actions: <Widget>[
FlatButton(
child: Icon(
Icons.save,
color: Colors.white,
),
onPressed: () => submit(context),
)
],
),
body: Container(
margin: EdgeInsets.all(10),
child: ListView(
children: <Widget>[
//KOMENTAR-1
],
),
),
);
}
}
Penjelasan: Struktur code di atas akan menampilkan sebuah Appbar dengan judul dan button untuk menyimpan data. Adapun komentar yang sudah dibuat akan menjadi marker dimana ketika komentar tersebut disebutkan, maka replace dengan code yang diinstruksikan.
Sebelum melengkapi code di atas, kita akan menghubungkan antara page employee dengan employee_add ini agar setiap perubahan yang baru bisa dilihat secara langsung. Buka file lib/pages/employee.dart
, modifikasi code berikut menjadi.
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.pink,
child: Text('+'),
onPressed: () {
//BUAT NAVIGASI UNTUK BERPINDAH KE HALAMAN EMPLOYEEADD
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => EmployeeAdd()));
},
),
Masih dengan file yang sama, tambahkan import statement:
import './employee_add.dart';
Kembali ke file lib/pages/employee_add.dart
, tambahkan code berikut untuk membuat kolom input-an name, salary dan age. Replace KOMENTAR-1 dengan code:
TextField(
controller: _name,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.pinkAccent,
),
),
hintText: 'Nama Lengkap',
),
//JIKA TOMBOL SUBMIT PADA KEYBOARD DITEKAN
onSubmitted: (_) {
//MAKA FOCUSNYA AKAN DIPINDAHKAN PADA FORM INPUT SELANJUTNYA
FocusScope.of(context).requestFocus(salaryNode);
},
),
TextField(
controller: _salary,
focusNode: salaryNode,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.pinkAccent,
),
),
hintText: 'Gaji',
),
onSubmitted: (_) {
FocusScope.of(context).requestFocus(ageNode);
},
),
TextField(
controller: _age,
focusNode: ageNode,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.pinkAccent,
),
),
hintText: 'Umur',
),
),
Kemudian definisikan controller untuk masing-masing input-an, masih dengan file yang sama, replace KOMENTAR-3 dengan code berikut
final TextEditingController _name = TextEditingController();
final TextEditingController _salary = TextEditingController();
final TextEditingController _age = TextEditingController();
FocusNode salaryNode = FocusNode();
FocusNode ageNode = FocusNode();
Adapun fungsi untuk meng-handle proses menambahkan data ke server, buka file lib/providers/employee_provider.dart
dan buat method baru sesuai code berikut
Future<bool> storeEmployee(String name, String salary, String age) async {
final url = 'http://employee-crud-flutter.daengweb.id/add.php';
//KIRIM REQUEST KE SERVER DENGAN MENGIRIMKAN DATA YANG AKAN DITAMBAHKAN PADA BODY
final response = await http.post(url, body: {
'employee_name': name,
'employee_salary': salary,
'employee_age': age
});
//DECODE RESPONSE YANG DITERIMA
final result = json.decode(response.body);
//LAKUKAN PENGECEKAN, JIKA STATUS CODENYA 200 DAN STATUS SUCCESS
if (response.statusCode == 200 && result['status'] == 'success') {
notifyListeners(); //MAKA INFORMASIKAN PADA LISTENERS BAHWA ADA DATA BARU
return true;
}
return false;
}
Untuk menggunakan fungsi di atas, buka kembali file employee_add.dart
dan modifikasi method submit()
menjadi.
void submit(BuildContext context) {
//MEMANGGIL FUNGSI YANG SUDAH DIDEFINISIKAN DI PROVIDER
//DENGAN MENGIRIMKAN VALUE DATA NAME, SALARY DAN AGE
Provider.of<EmployeeProvider>(context, listen: false)
.storeEmployee(_name.text, _salary.text, _age.text)
.then((res) {
//JIKA TRUE
if (res) {
//MAKA REDIRECT KE HALAMAN MENAMPILKAN DATA EMPLOYEE
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => Employee()));
} else {
//TAMPILKAN ALERT
}
});
}
Menampilkan Loading Progress
Dari sisi UX, diperlukan sebuah progress indicator sebagai pesan kepada user bahwa ada proses yang sedang berlangsung dibalik layar. Adapun untuk membuat efek loading di Flutter sangat mudah karena sudah disediakan widget-nya.
Buka file lib/pages/employee_add.dart
dan modifikasi kembali fungsi submit()
dengan mengubah value variable loading ketika tombol simpan di-tap.
void submit(BuildContext context) {
//KITA CEK, JIKA VALUENYA MASIH FALSE, MAKA AKAN PROSES CALL API AKAN DIJALANKAN
if (!_isLoading) {
//SET VALUE LOADING JADI TRUE, DAN TEMPATKAN DI DALAM SETSTATE UNTUK MEMBERITAHUKAN PADA WIDGET BAHWA TERJADI PERUBAHAN STATE
setState(() {
_isLoading = true;
});
//MASUKKAN FUNGSI PROVIDER, REDIRECT PAGE DAN SETERUSNYA KE DALAM SINI.
}
}
Masih dengan file yang sama, definisikan variable _isLoading
dengan tipe boolean.
bool _isLoading = false;
Bagian terakhir, modifikasi widget FlatButton yang ada pada bagian actions AppBar().
FlatButton(
//LAKUKAN PENGECEKAN, JIKA _ISLOADING TRUE MAKA TAMPILKAN LOADING
//JIKA FALSE, MAKA TAMPILKAN ICON SAVE
child: _isLoading
? CircularProgressIndicator(
//UBAH COLORNYA JADI PUTIH KARENA APPBAR KITA WARNA BIRU DAN DEFAULT LOADING JG BIRU
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
)
: Icon(
Icons.save,
color: Colors.white,
),
onPressed: () => submit(context),
)
Menampilkan Alert Snackbar
Tugas selanjutnya adalah meng-handle error yang didapatkan dari proses penyimpanan data. Dari API akan memberikan return berupa status error apabila salah satu atau beberapa data yang dikirimkan kosong. Berdasarkan status tersebut kita akan menampilkan snackbar sebagai notifikasi kepada user bahwa terjadi kesalahan.
Buka file lib/pages/employee_add.dart
, kemudian pada else statement di dalam method submit()
, tambahkan code.
var snackbar = SnackBar(content: Text('Ops, Error. Hubungi Admin'),);
snackbarKey.currentState.showSnackBar(snackbar);
setState(() {
_isLoading = false;
});
Dengan file yang sama, definisikan variable berikut
final snackbarKey = GlobalKey<ScaffoldState>();
Kemudian di dalam widget build()
, terdapat code yang me-return Scaffold. Tambahkan attribute key
return Scaffold(
key: snackbarKey, //TAMBAHKAN CODE INI
appBar: AppBar(
title: Text('Add Employee'),
Sentuhan terakhir adalah menghilangkan flag debug agar tidak menggangu tampilan dari tombol save, buka file main.dart
dan tambahkan attribute berikut di dalam widget MaterialApp.
debugShowCheckedModeBanner: false,
Baca Juga: Mengenal Widget Flutter #8: Membuat Craousel Slide Show Dengan List View & Page View
Kesimpulan
Memahami cara kerja HTTP request di Flutter, sepanjang artikel ini kita sudah belajar bagaimana melakukan request dengan method POST dan menampilkan data baru pada halaman list data pegawai. Selain itu kita juga belajar bagaimana membuat TextField untuk input data, berpindah antara page satu dengan page lainnya, mengirimkan value dari masing-masing input-an, dan lain sebagainya.
Adapun dokumentasi code bisa dilihat di Github.
Comments