Pada artikel ini kita sudah belajar bagaimana cara mengambil data dari basis data MySQL dan memasukkan ke dalam model. Kemudian dari model itu kita tampilkan ke dalam UI Flutter.
Tetapi masih ada yang kurang kayaknya bukan !? 😐
Iyap, data tampil di UI Flutter setelah kita lakukan hot restart di terminal VS Code / Command Prompt. Lalu terpikirkan atau tidak, jika dalam aplikasi WhatsApp kita harus terus menerus melakukan hot restart. Kira berapa kali dan berapa jumlah tangan yang harus menekan setiap tombol 'r' di keyboard agar pesan yang dikirim muncul ke UI WhatsApp tujuan. Lelah bukan !? 😖
Maka dari itu, kita akan mencoba membuat aplikasi kita otomatis menampilkan data yang ada dalam basis data jika terjadi penambahan ataupun perubahan data. Langsung saja yah kita buka projek WhatsApp kita kemarin yang sudah menggunakan sebuah model (artikel awal tentang static UI WhatsApp : klik disini ).
Selanjutnya kita hapus fungsi :
Future<List<Chat>> readListChats() async { }
Dan kita ganti dengan membuat sebuah fungsi baru :
void mulaiStreamReadingList() async { }
yang nantinya menggunakan sebuah controller :
StreamController<List<model_name>>
( lebih lanjut tentang StreamController : baca disini )
Awalannya kita buat controllernya, letakkan dibawah State Class :
class _MyHomePageState extends State<MyHomePage> {
final StreamController<List<Chat>> chatStreamController =
StreamController<List<Chat>>();
Lebih lengkap fungsinya nampak seperti :
void mulaiStreamReadingList() async {
Timer.periodic(Duration(seconds: 1), (timer) async {
var url = Uri.http("localhost", "/whatsapp/chats.php", {'q': '{http}'});
Pada awalnya kita set bahwa dalam setiap 1 detik kita akan memanggil server dan kemudian pada bagian ini :
void mulaiStreamReadingList() async {
Timer.periodic(Duration(seconds: 1), (timer) async {
var url = Uri.http("localhost", "/whatsapp/chats.php", {'q': '{http}'});
if (chatStreamController.isClosed) return timer.cancel();
final response = await http
.get(url, headers: {"Access-Control-Allow-Methods": "POST, OPTIONS"});
final items = json.decode(response.body).cast<Map<String, dynamic>>();
Ketika kita mendapatkan response dalam pengaksesan file chats.php, kita simpan response tersebut ke dalam variabel yang bernama items. Data tersebut kita ambil dan simpan dalam format JSON.
Kemudian dalam bagian ini :
List<Chat> chat = items.map<Chat>((json) {
return Chat.fromJson(json);
}).toList();
chatStreamController.sink.add(chat);
Kita menyimpan data hasil response tadi ke dalam model kita yang bernama Chat ( chats.dart ). Kita buat dalam bentuk List(), kemudian secara simultan kita tambahkan data yang ada dalam basis data melalui perintah :
chatStreamController.sink.add(chat);
Lebih lengkap fungsi dari mulai StreamReadingList() ini :
void mulaiStreamReadingList() async {
Timer.periodic(Duration(seconds: 1), (timer) async {
var url = Uri.http("localhost", "/whatsapp/chats.php", {'q': '{http}'});
if (chatStreamController.isClosed) return timer.cancel();
final response = await http
.get(url, headers: {"Access-Control-Allow-Methods": "POST, OPTIONS"});
final items = json.decode(response.body).cast<Map<String, dynamic>>();
List<Chat> chat = items.map<Chat>((json) {
return Chat.fromJson(json);
}).toList();
chatStreamController.sink.add(chat);
});
}
Netx, kita memanggil fungsi mulaiStreamReadingList(); melalui initState() :
@override
void initState() {
mulaiStreamReadingList();
super.initState();
}
Setelah berhasil, langkah selanjutnya kita set data yang telah kita ambil dari server untuk ditampilkan menggunakan widget Center() yang di dalamnya kita isi dengan widget StreamBuilder<<>>. Kita buat dalam tab bagian CHATS :
Center(
child: StreamBuilder<List<Chat>>(
stream: chatStreamController.stream,
builder: (context, snapshot) {
Dengan StreamBuilder tersebut kita mengubah aliran objek / data yang tersimpan dalam model Chat, kemudian dengan snapshot kita simpan data tersebut. Next :
Center(
child: StreamBuilder<List<Chat>>(
stream: chatStreamController.stream,
builder: (context, snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
Respon data ( snapshot ) yang kita dapat dari StreamBuilder lalu di cek, jika tidak memiliki data ( kosong ) maka dala UI Flutter akan menampilkan sebuah lingkaran progress loading ( widget CircularProgressIndicator() ). Jika data > 0 maka akan me-return sebuah widget ListView.builder().
Nanti data yang muncul akan sesuai dengan data yang ada, kita atur menggunakan properti :
itemCount: snapshot.data!.length,
Untuk selanjutnya data yang di snapshot kita lakukan indexing dalam properti :
itemBuilder: (context, index) {
final data = snapshot.data![index];
Lalu nanti akan me-return sebuah widget :
return InkWell(
child: ListTile(
leading: Icon(Icons.person),
title: Text(data.nama),
subtitle: Text(data.chat),
),
onTap: () {
print("Chat di tekan!");
},
);
Yang nantinya bisa terklik dan menampilkan sebuah layout mirip dengan chat yang ada dalam WhatsApp. Widget tersebut yaitu ListTile() yang memiliki properti leading untuk penempatan gambar, title dan subtile.
Baik sampai sini coba kita jalankan dengan flutter run, lalu coba tambahkan sebuah data dalam basis datanya...
Taraaaaa, otomatis refresh gaes 👌
Sip, sampai bagian ini kita sudah selesai untuk studi kasus aplikasi WhatsApp. Selanjutnya bisa kalian kembangkan lebih jauh, baik yang ada di tab STATUS dan PANGGILAN.
Selamat belajar 👌👌👌👌👌👌
Tags:
Flutter