[ Example ] Display Data dengan Model - WhatsApp UI

Setelah beberapa hari lalu dalam artikel ini kita belajar tentang bagaimana menampilkan data dari basis data secara langsung tanpa memisahkan objeknya, kali ini akan mempelajari bagaimana menampilkan data dengan cara menyambungkan ke sebuah model terlebih dahulu.
Kalau dalam bahasa Laravel, kita membuat modelnya. Sedang view-nya itu apa yang dibuat dengan widget-widget Flutter dan controller-nya adalah apa yang dibuat dengan php sebagai back end- nya.
  
 Apakah hasilnya berbeda ? Tentu tidak 😌

Tetap sama, hanya saja kita bisa lebih mudah dalam melakukan maintenance ( pemeliharaan ) ke depannya. Pertama kita buat sebuah folder baru untuk menyimpan modelnya yaitu di dalam folder lib :
🛈 NB :
( Nama folder bisa bebas, tapi disini kami menamai dengan models )

Kemudian di dalamnya kita buat file baru dengan nama chats.dart, dimana isi dari file tersebut yaitu :
class Chat {
   late int id_chat;
   String? nama;
   String? chat;

  Chat(
    this.id_chat,
    this.nama,
    this.chat,
  );

  Chat.fromJson(Map<String, dynamic> json) {
    id_chat = json["id_chat"];
    nama = json["nama"];
    chat = json["chat"];
  }
}

Kemudian pada bagian fungsi mengambil data dari basis data, kemarin menggunakan _getChats() yang isinya : 
  Future<void> _getChats() async {
    // ambil data chats
    var url = Uri.http("localhost", "/whatsapp/chats.php", {'q': '{http}'});

    var response = await http
        .get(url, headers: {"Access-Control-Allow-Methods": "POST, OPTIONS"});

    if (response.statusCode == 200) {
      print(chats);

      setState(() { // isikan data yang telah diambil dengan perintah setState
        chats = json.decode(response.body);
      });
    } else {
      throw Exception('Data gagal di ambil!');
    }
  }

🛈 Cek artikel ini kembali untuk memahami perintah tersebut!

Dimana ditas fungsi ini, kita mendeklarasikan sebuah variabel bertipe list :
List chats = [];

Untuk menampung respon / hasil dari fungsi _getChats().

Nah fungsi tersebut akan kita ganti dengan membuat fungsi baru yang menggunakan model. Setelah dibuat model tadi ( lihat model chats.dart diatas ), kita import model tersebut dengan baris perintah :
import 'dart:async';
import 'dart:convert';
import 'models/chats.dart'; // import model chats
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

Berada di bagian atas baris kode aplikasi. Kemudian kita hapus ( atau di jadikan komentar fungsi _getChats() ) lalu kita buat fungsi baru dengan nama :
  Future<List<Chat>> readListChats() async { }

Lengkapnya isi dari fungsi tersebut :
  Future<List<Chat>> readListChats() async {
    var url = Uri.http("localhost", "/whatsapp/chats.php", {'q': '{http}'});
    var response = await http
        .get(url, headers: {"Access-Control-Allow-Methods": "POST, OPTIONS"});

    final _listChats = json.decode(response.body) as List<dynamic>;
    print(_listChats);
    return _listChats.map((e) => Chat.fromJson(e)).toList();
  }

Dari fungsi ini, kita melampirkan model Chat ( file yang kita buat dengan nama chats.dart ), lalu dengan perintah :
return _listChats.map((e) => Chat.fromJson(e)).toList();

Kita mengisi data-data untuk model Chat dari respon hasil pengambilan data perintah sebelumnya, yaitu :
    var url = Uri.http("localhost", "/whatsapp/chats.php", {'q': '{http}'});
    var response = await http
        .get(url, headers: {"Access-Control-Allow-Methods": "POST, OPTIONS"});

    final _listChats = json.decode(response.body) as List<dynamic>;

Selanjutnya, langkah terakhir kita tinggal menampilkan datanya dengan UI Flutter. Sesuai rencana awal kita membuat UI WhatsApp, maka kita akan menggunakan widget ListTile(). Kita langsung fokus ke widget :
          body: TabBarView(
            children: [

Di bagian tab CHATS, kita buat widget baru :
              FutureBuilder(
                future:

Lebih lengkapnya :
body: TabBarView(
            children: [
              FutureBuilder(
                future: readListChats(),
                builder: (context, data) {
                  if (data.hasError) {
                    return Text("${data.error}");
                  } else if (data.hasData) {
                    var items = data.data as List<Chat>;
                    return ListView.builder(
                        itemCount: items == null ? 0 : items.length,
                        itemBuilder: (context, index) {
                          return
                          InkWell(
                            child: ListTile(
                              leading: Icon(Icons.person),
                              title: Text(items[index].nama.toString()),
                              subtitle: Text(items[index].chat.toString()),
                    ),
                    onTap: () {
                      print("Chat di tekan!");
                    },
                  );
                        });
                  }

                  return Center(
                    child: CircularProgressIndicator(),
                  );
                },
              ),

Dengan widget FutureBuilder() kita bisa menampung sebuah data yang diambil dari properti future :, yang artinya data yang akan datang di masa yang akan datang. Kemudian dengan properti builder : kita akan membuat / memberikan sesuatu jika dari future itu memberikan respon baik ( ada datanya ).
Nampak dari baris perintahnya :
future: readListChats(),

Kita melampirkan fungsi readListChats() yang di deklarasikan dengan Future<>. Lalu dengan perintah :
builder: (context, data) {

Kita ambil respon dari fungsi readListChats() dan memasukkan ke dalam variabel data. Kemudian dengan baris kode :
if (data.hasError) {
  return Text("${data.error}");
}

Kita lakukan cek, jika ternyata ada kesalahan ( error ) dalam variabel data itu maka akan menampilkan pesan yang di cetak dalam perintah ${data.error}. Lalu selanjutnya dengan :
else if (data.hasData) {
    var items = data.data as List<Chat>;
       return ListView.builder(

Jika ada respon ( data ) yang terambil maka data tersebut kita buat sebagai List. Selanjutnya dengan return ListView.builder() kita tampilkan UI-nya dengan kondisi yang terdapat dalam properti-properti :
return ListView.builder(
    itemCount: items == null ? 0 : items.length,
    itemBuilder: (context, index) {

Jumlah data dalam ListView diatur dengan properti itemCount dan UI-nya kita set dengan return yang ada di dalam itemBuilder :
itemBuilder: (context, index) {
                          return
                            InkWell(
                              child: ListTile(
                              leading: Icon(Icons.person),
                              title: Text(items[index].nama),
                              subtitle: Text(items[index].chat),
                            ),
                          onTap: () {
                            print("Chat di tekan!");
                          },
                  );
                        }

Dengan widget InkWell() kita bisa membuat sebuah tombol yang tidak nampak seperti button pada umumnya. Tetapi sama fungsinya, nantinya bisa di klik. Dengan baris kode :
title: Text(items[index].nama),

Kita menampilkan data nama yang tersimpan dalam model Chat dan telah kita alihkan penyimpanannya dalam variabel items. Setelah selesai, mari kita jalankan dan lihat hasilnya :

Oiya hampir lupa di atas bagian :
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(

Tambahkan initState() untuk memanggil dan menjalankan fungsi ketika aplikasi pertama kali dijalankan :
  @override
  void initState() {
    readListChats();   
    super.initState();
  } 

Yeaaayyy 😍
Berhasil gaes....


Ahmad Istakim

Alumni dari jurusan Manajemen Informatika di Universitas Sains Al-Qur'an (UNSIQ ) Wonosobo. Tertarik dalam bidang pendidikan, teknologi komputasi dan disiplin ilmu keislaman ( Tafsir, Hadits, Arudl, Nahwu-Sharaf, Fiqh maupun Aqidah ) - https://s.id/blog-islamQ. Pernah juga mengenyam pendidikan di beberapa pesantren yang ada di Kab. Wonosobo dan Kab. Purworejo

Posting Komentar

Lebih baru Lebih lama