Mengenal Widget Flutter #9: CRUD Data Pegawai Part 1

Mengenal Widget Flutter #9: CRUD Data Pegawai Part 1

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

flutter http request

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

flutter provider state management

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.

Category:
Share:

Comments