lifelong learner — urip iku urup, currently working on accenture.

Tutorial Ionic – Membuat CRUD dengan singleton

0
Degananda.com -

CRUD atau Create , read , update dan delete adalah fungsi basic dan hampir selalu ada pada suatu aplikasi. Bagiamankah cara membuat CRUD pada ionic dengan menggunakan singleton class untuk menyimpan datannya ? Silahkan simak ulasan ini.

What will we build

Pada ulasan ini kita akan membahas mengenai pembuatan CRUD (Create read update delete) pada ionic dengan menggunakan singleton class. Data akan tersimpan pada array yang berbentuk object. Kita akan menggunakan model dan provider. Metode pembuatan form yang akan digunakan yaitu FormBuilder (formgroup) karena kami rasa metode pembuatan form seperti itu paling cepat dan mudah. Jika anda belum familiar dengan istilah – istilah diatas terdapat ulasan mengenai angular form pada blog ini.

Versi ionic yang digunakan adalah 4.x sehingga harap disesuaikan dengan environment anda.

Pre-requisites

Kami sangat menyaran anda telah familiar dengan hal-hal berikut ini, namun jangan menjadi halamangan untuk tidak mencoba tutorial membuat CRUD dengan singleton class ini jadikanlah sebagai referensi untuk mempermudah pemahaman :

  1. Konsep pertukaran data dengan @input dan @output dari suatu komponen pada angular
  2. Services / Providers
  3. Depedency Injection (DI)
  4. Ionic component , page
  5. Formbuilder / formgroup / validators

ke empat hal tersebut telah kami bahas pada kategori “angular starter pack” monggo jika ingin mempelajarinnya terlebih dahulu. Untuk ionic anda dapat melihatnya pada kategori “ionic”.

Aplikasi pengelola note

Data yang akan diolah pada aplikasi yang akan dibuat adalah manajemen note. Note atau catatan memiliki dua buah property yakni :

  1. judul dari note atau yang akan kita tulis sebagai “judul_note
  2. isi dari note atau yang akan kita tulis sebagai “isi_note“.

Data diatas akan kita gambarkan dengan menggunakan model /  class sehingga dapat memenuhi kriteria object oriented programming (OOP). Meski membuat model sebenarnya tidak wajib. Namun dengan menggunakan model atau bahkan interfaces akan meningkatanr readibility dari source code kita.  berikut ini adalah sedikit use case yang menggambarkan apa saja yang dapat dilakukan oleh user.

Terdapat empat use case dengan aktor “user”. Yakni yang pertama adalah user dapat menambahkan note baru, yang kedua user dapat mengubah note tersebut (sesuai dengan note yang pilih pada UI), ketiga user dapat menghapus note (sesuai dengan note yang dipilih pada UI) dan terahir melihat note. Untuk kasus melihat daftar note ini tidak menggunakan paging artinnya data akan diburst seluruhnya. Karena pagging bukan menjadi titik berat dalam ulasan ini.

Database

Kita tidak menggunakan RDBMS ataupun Nosql melainkan hanyalah class singleton sederhana yang akan menyimpan data note tersebut dalam suatu array berbentuk object (object Note). Sehingga prosesnya akan menggunakan fungsi-fungsi yang melekat pada array, misalnya .push() untuk menambahkan dan lain sebagainnya yang nantinnya akan dibahas pada bagian providers.

Singleton ini bersifat temporary artinnya data hanya tersimpan saat aplikasi berjalan. Jika aplikasi ditutup oleh user dan dibuka kembali maka data-data yang telah ada sebelumnya akan hilang. Karena fokus ulasan ini adalah membuat form dan melakukan operasi CRUD sederhana dan nantinnya akan dibuat ulasan lanjutan yang akan mengkonversi perintah CRUD yang sebelumnya ditujukan pada singleton class menjadi http request a.k.a melakukan pemanggilan API (Application programming interfaces).

User interfaces

Ini adalah sedikit gambaran megenai aplikasi yang akan dibuat.

Halaman untuk menampilkan daftar note. Selain untuk menampilkan note juga teradapat FAB(Floating action button) yang digunakan untuk menuju halaman “form-note” guna menambahkan note. Tombol edit untuk melakukan edit note dan tombol delete untuk menghapus note.

halaman form untuk menambah ataupun mengubah note.

 

Page flow

Navigasi pada ionic (mobile) memiliki mekanisme yang berbeda jika dibandingkan dengan navigasi yang dilakukan pada website. Ionic menggunakan stack sebagai konsep navigasi. Dimana kita tidak berpindah-pindah secara bebas dari suatu halaman ke halaman lainnya layaknya website. Berikut ini adalah page flow yang akan ada pada aplikasi pengelola note yang akan dibuat.

kita hanya akan memiliki dua buah halaman yakni halaman list note dan juga halaman form-note. Pada halaman list ini akan berfungsi untuk menampilkan daftar note yang ada pada class singleton secara list. Pada halaman form-note , akan terdapat form yang digunakan untuk melakukan kegiatan “menambahkan note” dan “mengubah note”. Dua hal tersebut dapat kita akomodasi dalam satu form dengan memanfaatkan navigation parameter (menggunakan if else / kondisional).

Component

Halaman dan komponen merupakan dua hal yang berbeda pada ionic. Hal yang paling mendasarkan pada komponen tidak terdapat navigasi a.k.a tidak melakukan DI pada modul navigasi (navController /NavParameter). Sedangkan pada “halaman” terdapat navigasi. Sehingga, komponen merupakan bagian dari “halaman”. Berikut ini komponen-komponen yang ada pada halaman-halaman yang telah kita definisikan diatas.

halaman listnote akan menampilkan komponen note dimana pada komponen tersebut data note akan divisualisasikan dengan menggunakan <ion-card>. Agar mekanisme pertukaran data dapat berjalan antara halaman listnote dengan komponen note maka kami menggunakan input, output serta event emitter. Data yang akan diproses adalah “isi_note” dan juga “judul_note” sesuai dengan model kita definisikan. Untuk tombol actionnya terdapat dua buah tombol yaitu untuk edit dan juga delete.

Halaman “form-note” tidak memiliki komponen dari luar hanya berisikan elemen-elemen form input.

Implementasi

Pada bagian ini kita akan mengimplementasikan rancangan yang telah terdefinisi dibawah. Langkah – langkah tersebut akan dimulai dari yang paling awal yakni membuat project ionic hingga pada proses pengujian + deploy ke devices android kita (bukan pada emulator, karena keterbatasan spesifikasi laptop kami mohon dimaafkan hhe..).

langkah 1 – membuat project ionic baru

perintah yang digunakan untuk menambahkan project baru yaitu :

ionic start ionic-note sidemenu

kami menggunakan template awal “sidemenu”. Meski sidemenu pada ulasan ini masih belum digunakna. Karena nantinya diproyeksikan akan menggunakna side menu tersebut dikemudian hari sehingga kami memilih menggunakan template sidemenu.

langkah 2 – Membuat Model

Kita menggunakan class untuk model note agar memudahkan proses pengelolaan source code + agar lebih terstruktur dan mengikuti kaidah object oriented programming. Ionic CLI tidak menyediakan perintah untuk generate sehingga kita harus membuatnya sendiri. Buat folder bernama “models” dan buat file bernama note.model.ts. Isi dari model tersebut adalah sebagai berikut

export class NoteModel {

judul_note : String;
 isi_note : String;

constructor(judul_note : String, isi_note : String){ 
 this.judul_note = judul_note;
 this.isi_note = isi_note;
 }

}

pada class model ini kita akan mengexport suatu class yang fungsinya adalah mirip seperti “singleton” namun dia bersifat sebagai model. Seluruh note yang akan dimasukan kedalam data singleton formatnya akan disesuaikan dengan model note yang kita buat ini melalui proses instansiasi. Property yang harus ada adalah judul note berupa string dan juga isi note berupa string.

langkah 3 – Membuat page, komponen dan provider

terdapat dua halaman yang harus dibuat yaitu : “listnote” dan juga “form-note“. Sedangkan untuk services atau provider hanya menggunakan satu buah provider yang bernama “note“. Untuk komponen kita hanya menggunakan satu buah komponen yakni komponen “note“. Sebagaimana telah digambarkan pada bagian “component” diatas. Perintah yang digunakan

page

ionic generate page nama_page

komponen

ionic generate component nama_komponen

provider

ionic generate provider nama_provider

berikut ini adalah struktur folder project hingga pada langkah ke-3 ini yang mana telah mencakup seluruh file yang dibutuhkan.

langkah 4 – Coding komponen note

import { Component, Input, Output, EventEmitter } from '@angular/core';
import { NoteProvider } from './../../providers/note/note';

@Component({
 selector: 'note',
 templateUrl: 'note.html'
})
export class NoteComponent {

@Input() NoteContent;
 @Output() NoteDelete = new EventEmitter();
 @Output() NoteEdit = new EventEmitter();

constructor(private noteProvider : NoteProvider) {
 
 }

deleteNote(){
 this.NoteDelete.emit(this.NoteContent);
 }

editNote(){
 this.NoteEdit.emit(this.noteProvider.getNoteIndex(this.NoteContent));
 }


}

Komponen note diatas menggunakan input dan output untuk mengakomodasi pertukaran data. Pada bagian @input() digunakan untuk mendapatkan data yang berasal dari parent component yakni “listnote”. Kita akan memanggil provider untuk medapatkan data note dari listnote. Di halaman listnote komponen ini akan ditampilkan menggunakan list memanfaatkan fungsi looping. Data yang ada pada loop tersebut akan dikirimkan ke komponen note ini.

Komponen note merupakan komponen kecil yang reuseable. Setiap iterasi looping yang ada pada halaman listnote akan memberikan data pada komponen ini. Ingat bahwa angular adalah framework yang ditujukan untuk membangun suatu aplikasi yang tersusun dari komponen-komponen kecil.

Event emiiter digunakan pada output. Ini berfungsi untuk mentrigger fungsi delete ataupun edit note pada parent component. Pada komponen note tidak memiliki fungsi yang mengakses “provider” atau services. Keseluruhan fungsi yang mengkases provider kami serahkan pada parent component.

Berikut adalah view untuk dari komponen note

<ion-card>
 <ion-card-header>
 <h2>{{NoteContent.judul_note}}</h2>
 <p>2 Agustus 2010</p>
 </ion-card-header>
 <ion-card-content>
 <div style="word-wrap: break-word;">
 {{NoteContent.isi_note}}
 </div>
 </ion-card-content>

<ion-row>
 <ion-col>
 <button ion-button icon-left clear small (click)="editNote()">
 <ion-icon name="create"></ion-icon> Edit
 </button>
 </ion-col>
 <ion-col>
 <button ion-button icon-left clear small (click)="deleteNote()">
 <ion-icon name="trash"></ion-icon> Delete
 </button>
 </ion-col>
 </ion-row>
</ion-card>

langkah 5 – Coding provider/services

import { Injectable } from '@angular/core';
//import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

// model
import { NoteModel } from './../../models/note.model';

@Injectable()
export class NoteProvider {

  NoteList : Array<NoteModel> = [];

  constructor() {

  }

  addNote(value){
    this.NoteList.push(value);
  }

  getNoteSingle(noteIndex){
	  return this.NoteList[noteIndex];
	}

  getNoteIndex(note : NoteModel){
    // mencari index dari note terkait.
    return this.NoteList.indexOf(note);
  }

  ubahNote(noteIndex, newNote : NoteModel){
    // mencari index dari note terkait.
    this.NoteList[noteIndex] = newNote;
  }

  deleteNote(note : NoteModel){
    // mencari index dari note terkait.
    let noteIndex = this.NoteList.indexOf(note);
    this.NoteList.splice(noteIndex, 1);
  }

}

Services ini akan menggunakan model note yang telah kita buat untuk menstandarkan tipe data dan mengikuti aturan object oriented programming. Perlu di ingat bahwa services ini akan menggunakan decorator @injectable agar dapat dilakukan dependency injection(DI) pada komponen lainnya. Tanpa DI maka services tidak dapat digunakan. Services note ini akan berfungsi sebagai singleton(temporary local database) yang menyimpan data note dalam bentuk array yang bertipe object note(dari model note yang kita buat).

Sedikit penjelasan mengenai fungsi-fungsi pada services diatas. indexOf() merupakan fungsi yang digunakan untuk mendapatkan nilai index dari suatu object yang merupakan bagian(anggota/member) dari array. Splice digunakan untuk memecah array. Parameter yang kedua di isi dengan angka “1” agar yang di”pecah” adalah note yang akan didelete saja. NoteList[noteIndex] = newNote digunakan untuk mengubah nilai note pada index tersebut.

langkah 6 – Coding halaman “listnote”.

import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';

// Navigation Pages
import { FormNotePage } from './../form-note/form-note'

// Providers
import { NoteProvider } from './../../providers/note/note';

@Component({
  selector: 'page-listnote',
  templateUrl: 'listnote.html',
})
export class ListnotePage {

  constructor(public navCtrl: NavController, public navParams: NavParams, public noteProvider : NoteProvider) {
    console.log(this.noteProvider.NoteList);
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad ListnotePage');
  }

  /*
    Navigation
  */
  goToFormPage(){
    let formParameter = {
      action : 'add'
    }
    this.navCtrl.push(FormNotePage, formParameter);
  }

  /*
    Action
  */
  onDelete(event){
    this.noteProvider.deleteNote(event);
  }

  onEdit(event){
    let formParameter = {
      action : 'edit',
      id : event
    }
    this.navCtrl.push(FormNotePage, formParameter);
  }

}

Pada halaman ini akan berfokus pada pemanggilan fungsi-fungsi yang ada pada provider. Selain itu, karena pada komponen note kita menggunakan eventemitter, maka pada halaman ini terdapat dua fungsi yakni onEdit() dan juga onDelete() yang akan menangkap “event” yang di emit oleh komponen note yang kemudian akan diteruskan ke providers. Nilai yang diemit oleh komponen note adalah id atau index dari note tersebut pada array / noteList [].

Kode untuk view komponen listnote

<!--
  Generated template for the ListnotePage page.

  See http://ionicframework.com/docs/components/#navigation for more info on
  Ionic pages and navigation.
-->
<ion-header>

  <ion-navbar color="primary">
    <ion-title>Ionic Note 1.0</ion-title>
  </ion-navbar>

</ion-header>


<ion-content>
  <!-- FAB -->
  <ion-fab bottom right>
    <button ion-fab color="secondary" (click)="goToFormPage()">
      <ion-icon name="add"></ion-icon>
    </button>
  </ion-fab>
  <!-- end of FAB -->

  <!-- List Note -->

  <ion-list no-lines>

    <ion-card *ngIf="noteProvider.NoteList.length <= 0">
      <ion-card-content>
        Tidak ada note pada database.
      </ion-card-content>
    </ion-card>
    
    <div *ngIf="noteProvider.NoteList.length > 0">
      <ion-item *ngFor="let note of noteProvider.NoteList">
      <note [NoteContent]="note" (NoteDelete)="onDelete($event)" (NoteEdit)="onEdit($event)"></note>
      </ion-item>
    </div>




  </ion-list>
  <!-- end of List Note -->

</ion-content>

Pada bagian view, komponen note akan dipanggil dari halaman listnote ini dengan menggunakna mekanisme looping.

langkah 7 – Coding halaman “formnote”

import { Component } from '@angular/core';
import { NavController, NavParams, ToastController } from 'ionic-angular';
import { FormBuilder, Validators, FormGroup } from '@angular/forms';

import { NoteProvider  } from './../../providers/note/note';

//@IonicPage()
@Component({
  selector: 'page-form-note',
  templateUrl: 'form-note.html',
})
export class FormNotePage {

  formNote : FormGroup;
  noteIndex;

  constructor(public navCtrl: NavController, public navParams: NavParams, private fb : FormBuilder, public noteProvider : NoteProvider, private toastCtrl :  ToastController) {
    this.formNote = this.fb.group({
      judul_note : this.fb.control('', Validators.required),
      isi_note : this.fb.control('', Validators.required)
    });
    if(this.navParams.data.action == "edit"){
      // mendapatkan index note yang akan diedit
      this.noteIndex = this.navParams.data.id;
      // mendapatkan data note sesuai index
      let noteDataSingle = this.noteProvider.getNoteSingle(this.noteIndex);
      // memberikan nilai pada data note yang akan diedit
      this.formNote.controls['judul_note'].setValue(noteDataSingle.judul_note);
      this.formNote.controls['isi_note'].setValue(noteDataSingle.isi_note);
      
    } 
  }

  onSubmit(value){
    if(this.navParams.data.action == "add"){
      this.noteProvider.addNote(value);
      let toast = this.toastCtrl.create({
        message: 'Berhasil menambahkan note baru',
        duration: 3000
      });
      toast.present();
    } else {
      this.noteProvider.ubahNote(this.noteIndex, value); 
      let toast = this.toastCtrl.create({
        message: 'Berhasil mengubah note',
        duration: 3000
      });
      toast.present();     
    }
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad FormNotePage');
  }

}

Pada formnote ini terdapat dua fungsi yang diakomodasi yakni menambahkan note dan mengubah note. Ketika nilai parameter “action” bernilai add maka form akan berfungsi untuk menambahkan note. Sedangkan ketika nilai parameter “action” bernilai edit maka form akan berfungsi sebagai menubah note.

Namun ada yang berbeda yakni ketika parameter bernilai “edit” maka terdapat satu fungsi yang dipanggil dari provider yakni mendapatkan nilai dari note yang sedang di edit yang kemudian lansung diupdate ke form inputnya. Sehingga default value dari form akan berbeda pada form edit maupun add / tambah.

Toast adalah fungsi untuk menampilkan semacam notifikasi dibawah layar yang berfungsi untuk memberitahukan user atas kejadian tertentu. Pada kasus ini, event yang diberitahukan adalah saat note berhasil ditambahkan dan note berhasil diubah.

code untuk view komponen formnote

<ion-header>

  <ion-navbar color="primary">
    <ion-title>{{navParams.data.action}}  Note</ion-title>
  </ion-navbar>

</ion-header>


<ion-content>

  <form [formGroup]="formNote" (ngSubmit)="onSubmit(formNote.value)">
  <ion-list>
    
    <ion-item>
      <ion-label floating >Judul Note</ion-label>
      <ion-input type="text" formControlName="judul_note"></ion-input>
    </ion-item>

    <ion-item>
      <ion-label floating >Isi Note</ion-label>
      <ion-input type="text" formControlName="isi_note"></ion-input>
    </ion-item>

    <ion-item>
      <button ion-button full color="secondary" style="height: 35px;">Submit</button>
    </ion-item>

  </ion-list>
  </form>

</ion-content>

done~