Kali ini kita akan belajar menghubungkan aplikasi flutter dengan API CodeIgniter. Sebelum lanjut kita harus sudah mencoba panduan “Membuat Aplikasi Android Sampai Rilis di Play Store” terlebih dahulu. Pastikan aplikasi sudah bisa dijalankan. Sebelumnya Aplikasi Catatan Harian menggunakan Shared Preferences / local storage untuk mengolah data. Kali ini kita akan mengupdate aplikasi dengan Rest API.
Daftar Rest API yang akan digunakan:
- GET : https://demo.belajaraplikasi.com/backend-ci/daftarcatatan
- POST : https://demo.belajaraplikasi.com/backend-ci/tambahcatatan
- POST : https://demo.belajaraplikasi.com/backend-ci/ubahcatatan
- GET : https://demo.belajaraplikasi.com/backend-ci/hapuscatatan


Buka project flutter (Aplikasi Catatan Harian) yang sudah dibuat.
Pertama kita tambahkan library / dependencies “http: ^0.12.2” di pubspec.yaml terlebih dahulu. Lalu ketik perintah di terminal : flutter pub get.

Buat file baru dengan nama “endpoint.dart“. Untuk menyimpan daftar API yang digunakan. Ketikkan code seperti berikut:
const BASE_URL = 'https://demo.belajaraplikasi.com/backend-ci';
const DAFTAR_CATATAN = BASE_URL + '/daftarcatatan';
const TAMBAH_CATATAN = BASE_URL + '/tambahcatatan';
const UBAH_CATATAN = BASE_URL + '/ubahcatatan';
const HAPUS_CATATAN = BASE_URL + '/hapuscatatan';
Selanjutnya kita membuat Model untuk menampung respon API. Buat file baru dengan nama “data.dart“. Ketikkan code seperti berikut:
class ListCatatan {
final int id;
final String judul;
final String tanggal;
final String catatan;
ListCatatan({this.id, this.judul, this.tanggal, this.catatan});
factory ListCatatan.fromJson(<String, dynamic> json) {
return ListCatatan(
id: json['id'],
tanggal: json['tanggal'],
judul: json['judul'],
catatan: json['catatan'],
);
}
}
Hapus “function_olah_data.dart” dan buat file baru dengan nama “bantuan.dart“. Ketikkan code seperti berikut :
import 'package:intl/intl.dart'; import 'package:intl/date_symbol_data_local.dart'; String formatDateFromString(String date) { initializeDateFormatting(); DateTime dateFormat = DateFormat("yyyy-MM-dd hh:mm:ss").parse(date); return DateFormat('EEEE, dd MMMM yyyy hh:mm:ss', 'id_ID').format(dateFormat); } String formatDateFromDateTime(DateTime date) { initializeDateFormatting(); return DateFormat('EEEE, dd MMMM yyyy hh:mm:ss', 'id_ID').format(date); } String formatDateYMDFromDateTime(DateTime date) { initializeDateFormatting(); return DateFormat('yyyy-MM-dd hh:mm:ss', 'id_ID').format(date); }
Di dalam folder Daftar, ubah file “daftar.dart” menjadi seperti berikut:
import 'dart:convert'; import 'package:catatan_harian/endpoint.dart'; import 'package:http/http.dart' as http; import 'package:catatan_harian/catatan/catatan.dart'; import 'package:catatan_harian/daftar/loading.dart'; import 'package:flutter/material.dart'; import 'daftar_konten.dart'; import 'daftar_kosong.dart'; import '../data.dart'; class Daftar extends StatefulWidget { @override _DaftarState createState() => _DaftarState(); } class _DaftarState extends State<Daftar> { void tambahCatatan() async { final result = await Navigator.push( context, MaterialPageRoute( builder: (context) => Catatan( tanggal: '', judul: '', catatan: '', ), ), ); if (result != null) { setState(() { futureCatatan = fetchDaftarCatatan(); }); } } void ubahCatatan(int id, String tanggal, String judul, String catatan) async { final result = await Navigator.push( context, MaterialPageRoute( builder: (context) =&gt; Catatan( id: id, tanggal: tanggal, judul: judul, catatan: catatan, ), ), ); if (result != null) { setState(() { futureCatatan = fetchDaftarCatatan(); }); } } Future<void> hapusCatatan(int id) async { final response = await http.get('$HAPUS_CATATAN?id=$id'); if (response.statusCode == 200) { } else { throw Exception('Gagal Menghapus Catatan'); } setState(() { Navigator.pop(context); futureCatatan = fetchDaftarCatatan(); }); } Future<List<ListCatatan>> fetchDaftarCatatan() async { final response = await http.get('$DAFTAR_CATATAN'); if (response.statusCode == 200) { if (response.body != 'false') { Map<String, dynamic> json = jsonDecode(response.body); List<ListCatatan> produkList = []; for (final item in json['data']) { produkList.add(ListCatatan.fromJson(item)); } return produkList; } else { return null; } } else { throw Exception('Gagal Menampilkan Daftar Catatan'); } } Future<List<ListCatatan>> futureCatatan; @override void initState() { super.initState(); futureCatatan = fetchDaftarCatatan(); } @override Widget build(BuildContext context) { return FutureBuilder<List<ListCatatan>>( future: futureCatatan, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasData) { return DaftarKonten( snapshot: snapshot, ubahCatatan: ubahCatatan, hapusCatatan: hapusCatatan, tambahCatatan: tambahCatatan, ); } else { return DaftarKosong(tambahCatatan: tambahCatatan); } } return Loading(); }, ); } }
Selanjutnya masih di dalam folder Daftar, ubah juga file “daftar_kontent.dart” menjadi seperti berikut:
import 'package:catatan_harian/daftar/daftar_catatan.dart'; import 'package:catatan_harian/data.dart'; import 'package:flutter/material.dart'; class DaftarKonten extends StatelessWidget { DaftarKonten({ @required this.snapshot, @required this.hapusCatatan, @required this.ubahCatatan, @required this.tambahCatatan, }); final AsyncSnapshot<List<ListCatatan>> snapshot; final Function(int) hapusCatatan; final Function(int, String, String, String) ubahCatatan; final Function tambahCatatan; Future dialogHapus(BuildContext context, String judul, int id) { return showDialog( context: context, builder: (_) => AlertDialog( title: Text( 'Yakin "$judul" akan dihapus?', style: TextStyle(fontSize: 12), ), content: InkWell( onTap: () => hapusCatatan(id), child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Color(0xFF1761a0), borderRadius: BorderRadius.circular(6), ), child: Text( 'Hapus', style: TextStyle( fontSize: 14, color: Colors.white, ), textAlign: TextAlign.center, ), ), ), ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Catatan Harian'), backgroundColor: Color(0xFF1761a0), ), body: SafeArea( child: Container( child: ListView.builder( physics: const ClampingScrollPhysics(), itemCount: snapshot.data.length, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: InkWell( onLongPress: () => dialogHapus( context, snapshot.data[index].judul, snapshot.data[index].id, ), onTap: () => ubahCatatan( snapshot.data[index].id, snapshot.data[index].tanggal, snapshot.data[index].judul, snapshot.data[index].catatan, ), child: Column( children: <Widget>[ DaftarCatatan( tanggal: snapshot.data[index].tanggal, judul: snapshot.data[index].judul, catatan: snapshot.data[index].catatan, ), Divider(height: 1), ], ), ), ); }, ), ), ), floatingActionButton: FloatingActionButton( backgroundColor: Color(0xFF1761a0), onPressed: tambahCatatan, child: Icon(Icons.add), ), ); } }
Lalu masih dalam folder yang sama, ubah juga file “daftar_catatan.dart” menjadi seperti berikut:
import 'package:flutter/material.dart'; import 'package:share/share.dart'; class DaftarCatatan extends StatelessWidget { DaftarCatatan({ @required this.tanggal, @required this.judul, @required this.catatan, }); final String tanggal; final String judul; final String catatan; void bagikanCatatan() { Share.share( '$tanggal\n$judul\n$catatan'); } @override Widget build(BuildContext context) { return Row( children: <Widget>[ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ SizedBox(height: 10), Text( '$tanggal', style: TextStyle(color: Colors.grey, fontSize: 10), ), SizedBox(height: 3), Text( '$judul', style: TextStyle( color: Colors.grey[800], fontWeight: FontWeight.bold, fontSize: 16, ), ), SizedBox(height: 5), Text( '$catatan', style: TextStyle(color: Colors.grey[700], fontSize: 14), overflow: TextOverflow.ellipsis, maxLines: 1, ), SizedBox(height: 10), ], ), ), InkWell( onTap: () => bagikanCatatan(), child: Icon( Icons.share, color: Colors.grey[350], size: 18, ), ), Padding( padding: const EdgeInsets.only(left: 12), child: Icon( Icons.arrow_forward_ios, color: Colors.grey[350], size: 18, ), ), ], ); } }
Pindah ke folder catatan, ubah file “catatan.dart” menjadi seperti berikut:
import 'dart:convert'; import 'package:catatan_harian/bantuan.dart'; import 'package:catatan_harian/catatan/isi_catatan.dart'; import 'package:catatan_harian/catatan/judul_catatan.dart'; import 'package:catatan_harian/catatan/simpan_catatan.dart'; import 'package:catatan_harian/catatan/tanggal_catatan.dart'; import 'package:catatan_harian/endpoint.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:intl/date_symbol_data_local.dart'; import 'package:http/http.dart' as http; class Catatan extends StatefulWidget { Catatan({ this.id, @required this.tanggal, @required this.judul, @required this.catatan, }); final int id; final String tanggal; final String judul; final String catatan; @override _CatatanState createState() => _CatatanState(id: id, tanggal: tanggal, judul: judul, catatan: catatan); } class _CatatanState extends State<Catatan> { _CatatanState({ this.id, @required this.tanggal, @required this.judul, @required this.catatan, }); int id; String tanggal; String judul; String catatan; TextEditingController judulController = TextEditingController(); TextEditingController catatanController = TextEditingController(); Future<void> onPressedSimpan() async { if (id != null) { judul = judulController.text; catatan = catatanController.text; final response = await http.post( Uri.parse('$UBAH_CATATAN'), headers: <String, String>{ 'Content-Type': 'application/json; charset=UTF-8', }, body: jsonEncode(<String, String>{ 'id': id.toString(), 'tanggal': tanggal, 'judul': judul, 'catatan': catatan }), ); if (response.statusCode == 200) { Navigator.pop(context, 'berhasil'); } else { throw Exception('Gagal untuk mengubah catatan'); } } else { String judul = judulController.text; String catatan = catatanController.text; final response = await http.post( Uri.parse('$TAMBAH_CATATAN'), headers: <String, String>{ 'Content-Type': 'application/json; charset=UTF-8', }, body: jsonEncode(<String, String>{ 'tanggal': formatDateYMDFromDateTime(DateTime.now()), 'judul': judul, 'catatan': catatan }), ); if (response.statusCode == 200) { Navigator.pop(context, 'berhasil'); } else { throw Exception('Gagal untuk menyimpan catatan'); } } } @override Widget build(BuildContext context) { const locale = 'id'; initializeDateFormatting(locale).then((_) { DateFormat.Hm(locale); }); if (id != null) { judulController.text = judul; catatanController.text = catatan; } return Scaffold( appBar: AppBar( title: Text(id == null ? 'Tambah Catatan' : 'Ubah Catatan'), backgroundColor: Color(0xFF1761a0), ), body: Builder( builder: (context) => SafeArea( child: Container( child: Stack( children: <Widget>[ ListView( physics: const ClampingScrollPhysics(), children: <Widget>[ Column( crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ SizedBox(height: 10), TanggalCatatan( id: id, tanggal: tanggal, ), JudulCatatan(judulController: judulController), Divider(height: 1), IsiCatatan(catatanController: catatanController), ], ), SizedBox(height: 45), ], ), SimpanCatatan(onPressedSimpan: onPressedSimpan), ], ), ), ), ), ); } }
Masih dalam folder catatan, ubah juga file “tanggal_catatan.dart” menjadi seperti berikut:
import 'dart:convert'; import 'package:catatan_harian/bantuan.dart'; import 'package:catatan_harian/catatan/isi_catatan.dart'; import 'package:catatan_harian/catatan/judul_catatan.dart'; import 'package:catatan_harian/catatan/simpan_catatan.dart'; import 'package:catatan_harian/catatan/tanggal_catatan.dart'; import 'package:catatan_harian/endpoint.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:intl/date_symbol_data_local.dart'; import 'package:http/http.dart' as http; class Catatan extends StatefulWidget { Catatan({ this.id, @required this.tanggal, @required this.judul, @required this.catatan, }); final int id; final String tanggal; final String judul; final String catatan; @override _CatatanState createState() => _CatatanState(id: id, tanggal: tanggal, judul: judul, catatan: catatan); } class _CatatanState extends State<Catatan> { _CatatanState({ this.id, @required this.tanggal, @required this.judul, @required this.catatan, }); int id; String tanggal; String judul; String catatan; TextEditingController judulController = TextEditingController(); TextEditingController catatanController = TextEditingController(); Future<void> onPressedSimpan() async { if (id != null) { judul = judulController.text; catatan = catatanController.text; final response = await http.post( Uri.parse('$UBAH_CATATAN'), headers: <String, String>{ 'Content-Type': 'application/json; charset=UTF-8', }, body: jsonEncode(<String, String>{ 'id': id.toString(), 'tanggal': tanggal, 'judul': judul, 'catatan': catatan }), ); if (response.statusCode == 200) { Navigator.pop(context, 'berhasil'); } else { throw Exception('Gagal untuk mengubah catatan'); } } else { String judul = judulController.text; String catatan = catatanController.text; final response = await http.post( Uri.parse('$TAMBAH_CATATAN'), headers: <String, String>{ 'Content-Type': 'application/json; charset=UTF-8', }, body: jsonEncode(<String, String>{ 'tanggal': formatDateYMDFromDateTime(DateTime.now()), 'judul': judul, 'catatan': catatan }), ); if (response.statusCode == 200) { Navigator.pop(context, 'berhasil'); } else { throw Exception('Gagal untuk menyimpan catatan'); } } } @override Widget build(BuildContext context) { const locale = 'id'; initializeDateFormatting(locale).then((_) { DateFormat.Hm(locale); }); if (id != null) { judulController.text = judul; catatanController.text = catatan; } return Scaffold( appBar: AppBar( title: Text(id == null ? 'Tambah Catatan' : 'Ubah Catatan'), backgroundColor: Color(0xFF1761a0), ), body: Builder( builder: (context) => SafeArea( child: Container( child: Stack( children: <Widget>[ ListView( physics: const ClampingScrollPhysics(), children: <Widget>[ Column( crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ SizedBox(height: 10), TanggalCatatan( id: id, tanggal: tanggal, ), JudulCatatan(judulController: judulController), Divider(height: 1), IsiCatatan(catatanController: catatanController), ], ), SizedBox(height: 45), ], ), SimpanCatatan(onPressedSimpan: onPressedSimpan), ], ), ), ), ), ); } }
Run flutter project. Selesai.
Source Code Lengkap : https://github.com/handoyoapp/catatan_harian
Selamat mencoba.
Happy Coding 🙂
I’m a result mobile engineer, as well as deep understanding of digital systems.
halo kak apa ada source untuk backendnya?
ada silahkan https://github.com/handoyoapp/backend-ci
Terima kasih sudah berkunjung 🙂
Terimakasih kak. Sangat bermanfaat. Sedang belajar tentang web.