Ilmu Coding Ilmucoding.com - Merupakan situs yang membantu Anda belajar coding lebih mudah, nyaman, interaktif dan profesional. Belajar sekarang di ilmu coding. GRATIS

Tutorial CRUD Codeigniter 4 dan Flutter #4 – Update Data

4 min read

CRUD Codeigniter 4 + Flutter - Update Data

Tutorial CRUD Codeigniter 4 dan Flutter #4 – Update Data. Kali ini saya akan melanjutkan pembahasan sebelumnya yaitu edit dan update data.

Sebelum melanjutkan, jika Anda belum membaca dan mempraktikan part ke 3 tentang detail data, silahkan kunjungi:

Rekomendasi: Tutorial CRUD Codeigniter 4 dan Flutter #3 – Detail Data

Bila sudah, sekarang kita akan melanjutkan langkah berikutnya. Yaitu membuat halaman edit dan proses update data di Flutter dan mengirimkan data (method POST) melalui REST API Codeigniter 4.

Silahkan ikuti beberapa langkah di bawah ini:

Step 1 – Tambahkan Function Update User di Model User

Silahkan buka file User_model.php yang ada di dalam direktori app/Models.

Kemudian ketik kode berikut ini:

public function updateUser($data, $id)
{
    return $this->db->table($this->table)->update($data, ['id' => $id]);
}

Penjelasan:

Pada bagian ini kita melakukan update data berdasarkan parameter id sebagai primary key dari table users.

Step 2 – Tambahkan Function Update di Controller

public function update($id = NULL)
{
    $fullname   = $this->request->getPost('fullname');
    $grade      = $this->request->getPost('grade');
    $gender     = $this->request->getPost('gender');
    $phone      = $this->request->getPost('phone');
    
    $data = [
        'fullname' => $fullname,
        'grade' => $grade,
        'gender' => $gender,
        'phone' => $phone
    ];
    
    $simpan = $this->model->updateUser($data, $id);
    
    if($simpan){
        $msg = ['message' => 'Updated user successfully'];
        $response = [
            'status' => 200,
            'error' => false,
            'data' => $msg,
        ];
        return $this->respond($response, 200);
    }
}

Penjelasan:

Biasanya proses edit menggunakan method PUT, tapi di sini saya menggunakan method POST.

Menurut saya ga masalah kalau kita menggunakan POST. Ini sejalan dengan dokumentasi Codeigniter 4 yang membolehkan menggunakan presenter.

Anda bisa membaca dokumentasi lengkap tentang Codeigniter 4 Rest API di sini.

Step 3 – Testing Update Data Melalui Postman

Silahkan gunakan URL ke 1 ini:

localhost:8080/user/update/id

… atau URL ke 2 ini:

 localhost/belajar-codeigniter-4/ci4_restapi_flutter/public/index.php/user/update/id

Catatan:

Silahkan ubah kata id yang saya cetak tebal dengan id / primary key yang tersedia di table users pada komputer Anda.

Jika berjalan dengan lancar, hasilnya adalah:

Tutorial CRUD Codeigniter 4 dan Flutter #3 – Update Data - Gambar 1

Step 4 – Tambahkan Function Update User di User Service

Buka kembali file user_service.dart pada direktori lib/service.

Kemudian ketik kode berikut ini:

Future<bool> updateUser({int id, User data}) async {
  final response = await client.post(
    "$baseUrl/user/update/$id",
    body: {
      "fullname" : data.fullName,
      "grade" : data.grade,
      "gender" : data.gender,
      "phone" : data.phone 
    }
  );
  if (response.statusCode == 200) {
    return true;
  } else {
    return false;
  }
}

Step 5 – Buat Halaman Edit Data

Kemudian buat file baru bernama user_edit.dart dan simpan di dalam direktori lib/screen.

lib/screen/user_edit.dart

import 'package:flutter/material.dart';
import 'package:flutter_crud_ci4/model/user.dart';
import 'package:flutter_crud_ci4/service/user_service.dart';
import 'package:flutter_crud_ci4/util/capitalize.dart';
import 'package:flutter_crud_ci4/widget/form_label.dart';
import 'package:flutter_crud_ci4/widget/radio_button.dart';

class FormEditUser extends StatefulWidget {

  final User user;
  final int id;

  FormEditUser({@required this.user, @required this.id, Key key}):super(key: key);

  @override
  _FormEditUserState createState() => _FormEditUserState();
}

class _FormEditUserState extends State<FormEditUser> {

  UserApiService apiService;

  static const genders = User.genders; // from domain
  static const grades = User.grades; // from domain

  // upayakan menggunakan global key
  final _formKey = GlobalKey<FormState>();
  final GlobalKey<ScaffoldState> _scaffoldkey = GlobalKey<ScaffoldState>();

  bool _autovalidate = false;
  // jarak antar form
  double _gap = 16.0;
  // focus node
  FocusNode _fullnameFocus, _phoneFocus;
  // variabel value null
  String _fullname, _gender, _grade, _phone;

  TextEditingController _fullnameController, _phoneController;

  final List<DropdownMenuItem<String>> _gradeItems = grades
    .map((String val) => DropdownMenuItem<String>(
          value: val,
          child: Text(val.toUpperCase()),
        ))
    .toList();

  @override
  void initState() {
    super.initState();
    _gender = 'pria';
    _fullnameFocus = FocusNode();
    _phoneFocus = FocusNode();
    _fullnameController = TextEditingController();
    _phoneController = TextEditingController();

    if(widget.user != null &amp;&amp; widget.id != null){
      _fullname = widget.user.fullName;
      _phone = widget.user.phone;
      _gender = widget.user.gender;
      _grade = widget.user.grade;

      _fullnameController.value = TextEditingValue(
        text: widget.user.fullName,
        selection: TextSelection.collapsed(offset: widget.user.fullName.length)
      );

       _phoneController.value = TextEditingValue(
        text: widget.user.phone,
        selection: TextSelection.collapsed(offset: widget.user.phone.length)
      );

    }

    apiService = UserApiService();
  }

  @override
  void dispose() {
    // Clean up the focus node when the Form is disposed.
    _fullnameFocus.dispose();
    _phoneFocus.dispose();
    _fullnameController.dispose();
    _phoneController.dispose();
    _formKey.currentState?.dispose();
    super.dispose();
  }

  _showSnackBar(message){
    final snackbar = SnackBar(content: Text(message),);
    _scaffoldkey.currentState.showSnackBar(snackbar);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldkey,
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(Icons.arrow_back),
          onPressed: () => {
            Navigator.pop(context),
          },
        ),
        title: Text("Edit User"),
      ),
      body: SingleChildScrollView(
        child: ConstrainedBox(
          constraints: BoxConstraints(),
          child: Form(
            // key form as csrf
            key: _formKey,
            autovalidate: _autovalidate,
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  TextFormField(
                    controller: _fullnameController,
                    focusNode: _fullnameFocus,
                    textInputAction: TextInputAction.next,
                    keyboardType: TextInputType.text,
                    decoration: const InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Nama Lengkap',
                    ),
                    onSaved: (String value) {
                      // will trigger when saved
                      print('onsaved _fullname $value');
                      _fullname = value;
                    },
                    onFieldSubmitted: (term) {
                      _fullnameFocus.unfocus();
                      FocusScope.of(context).requestFocus(_phoneFocus);
                    },
                    validator: (val) {
                      if(val.isEmpty){
                        return "Nama lengkap wajib diisi";
                      }
                      return null;
                    },
                  ),
                  SizedBox(
                    height: _gap,
                  ),
                  TextFormField(
                    controller: _phoneController,
                    focusNode: _phoneFocus,
                    textInputAction: TextInputAction.next,
                    keyboardType: TextInputType.phone,
                    decoration: const InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'No. Hp',
                    ),
                    onSaved: (String value) {
                      // will trigger when saved
                      print('onsaved _hone $value');
                      _phone = value;
                    },
                    onFieldSubmitted: (term) {
                      _phoneFocus.unfocus();
                      FocusScope.of(context).requestFocus(_fullnameFocus);
                    },
                    validator: (val) {
                      if(val.isEmpty){
                        return "No hp wajib diisi";
                      }
                      return null;
                    },
                  ),
                  SizedBox(
                    height: _gap,
                  ),
                  FormLabel('Jenis Kelamin'),
                  Row(
                    children: genders
                        .map((String val) => RadioButton<String>(
                            value: val,
                            groupValue: _gender,
                            label: Text(capitalize(val)),
                            onChanged: (String value) {
                              setState(() => _gender = value);
                            }))
                        .toList(),
                  ),
                  SizedBox(
                    height: _gap,
                  ),
                  FormLabel('Jenjang'),
                  Padding(
                    padding: const EdgeInsets.only(left: 5.0),
                    child: DropdownButton(
                      value: _grade,
                      hint: Text('Pilih jenjang'),
                      items: _gradeItems,
                      isExpanded: true,
                      onChanged: (String value) {
                        setState(() {
                          _grade = value;
                        });
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(
          Icons.save,
          color: Colors.white,
        ),
        onPressed: () {
          final form = _formKey.currentState;
          if (form.validate()) {
            // Process data.
            form.save(); // required to trigger onSaved props
            User _user = User();

            if(_grade == null){
              _showSnackBar("Jenjang tidak boleh kosong");
            } else if(_gender == null){
              _showSnackBar("Gender tidak boleh kosong");
            } else {
              _user.fullName = _fullname;
              _user.grade = _grade;
              _user.gender = _gender;
              _user.phone = _phone;
              print(_user);

              // snackbar success dan error
              final onSuccess = (Object success) => Navigator.pop(context);
              final onError = (Object error) => _showSnackBar("Tidak bisa ubah data");
              
              apiService.updateUser(id: widget.user.id, data: _user).then(onSuccess).catchError(onError);
            }
          } else {
            setState(() {
              _autovalidate = true;
            });
          }
        }
      ),
    );
  }
}

Step 6 – Modifikasi File Detail di Flutter

Buka kembali file user_detail.dart pada direktori lib/screen.

Kemudian cari kode berikut ini:

...
...
IconButton(
  icon: Icon(Icons.edit), 
  onPressed: () {}
),
...
...

Ubah menjadi:

...
...
IconButton(
  icon: Icon(Icons.edit), 
  onPressed: () {
    Navigator.push(context, 
    MaterialPageRoute(builder: (BuildContext context) => FormEditUser(
      user: _user,
      id: widget.id),
      ),
    );
  }
),
...
...

Step 7 – Testing Proses Update Data

Now, kita akan menjalankan project menggunakan perintah:

flutter run

Jika berjalan dengan lancar, berikut hasilnya:

Apa Selanjutnya?

Alhamdulillah, tutorial crud codeigniter 4 dan flutter part ke 4 – update data sudah selesai.

… tapi jangan puas dulu ya. Sebab masih ada pembahasan soal delete data.

… dan saya berharap, semoga tidak ada error yang dialami oleh teman-teman semuanya.

Jika pun ada, Anda bisa bertanya di kolom komentar atau mau lihat-lihat dulu perubahan source code yang ada di Github (perhatikan commit part 4 nya ya).

Ini linknya: Commit Part 4 – Update Data

Semoga tutorial crud codeigniter 4 dan flutter part ke 4 – update data ini bermanfaat dan selamat belajar …

Ilmu Coding Ilmucoding.com - Merupakan situs yang membantu Anda belajar coding lebih mudah, nyaman, interaktif dan profesional. Belajar sekarang di ilmu coding. GRATIS

Leave a Reply

Your email address will not be published. Required fields are marked *

Jika terbantu dengan artikel ini, silahkan share, beri komentar dan "klik" 1 kali pada iklan ya.