Implementasi Reactive Form – 1

Untuk kelengkapan tutorial, pada modul ini akan membahas penggunaan reactive form untuk edit recipe. Untuk pembahasan dasar mengenai Reactive Form bisa lihat di modul : https://skillplus.web.id/angular-reactive-forms-1/

Setup Reactive Form

Pertama, kita buka file app.module.ts, tambahkan library reactive forms module.

import { NgModule} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
// tambahkan lib ReacTiveFormsModule, jika IDE tidak otomatis
import {FormsModule, ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { RecipesComponent } from './recipes/recipes.component';
import { RecipeListComponent } from './recipes/recipe-list/recipe-list.component';
import { RecipeDetailComponent } from './recipes/recipe-detail/recipe-detail.component';
import { RecipeItemComponent } from './recipes/recipe-list/recipe-item/recipe-item.component';
import { ShoppingListComponent } from './shopping-list/shopping-list.component';
import { ShoppingEditComponent } from './shopping-list/shopping-edit/shopping-edit.component';
import { DropDownDirective } from './shared/dropdown.directive';
import { ShoppingListService } from './shopping-list/shopping-list.service';
import { AppRoutingModule } from './app-routing.module';
import { RecipeHomeComponent } from './recipes/recipe-home/recipe-home.component';
import { RecipeEditComponent } from './recipes/recipe-edit/recipe-edit.component';

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    RecipesComponent,
    RecipeListComponent,
    RecipeDetailComponent,
    RecipeItemComponent,
    ShoppingListComponent,
    ShoppingEditComponent,
    DropDownDirective,
    RecipeHomeComponent,
    RecipeEditComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule, // ditambahkan karena menggunakan reactive form
    AppRoutingModule
  ],
  providers: [ShoppingListService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Membuat Form Template

Buka file edit-recipe.component.html, kita buat template form seperti berikut:

<div class="row">
    <div class="col-xs-12">
        <form>
            <div class="row">
                <div class="col-12">
                    <button type="submit" class="btn btn-success">Save</button>
                    <button type="submit" class="btn btn-danger">Cancel</button>
                </div>
            </div>
            <div class="row">
                <div class="col-12">
                    <div class="form-group">
                        <label for="name">Name</label>
                        <input type="text" class="form-control" id="name">
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-12">
                    <div class="form-group">
                        <label for="imgPath">Image URL</label>
                        <input type="text" class="form-control" id="imgPath">
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-12">
                    <img src="" class="img-fluid.">
                </div>
            </div>            
            <div class="row">
                <div class="col-12">
                    <div class="form-group">
                        <label for="description">Description</label>
                        <textarea class="form-control" id="description" rows="5"></textarea>
                    </div>
                </div>
            </div>
            <div class="row mt-2">
                <div class="col-12">
                    <div class="row">
                        <div class="col-8">
                            <input type="text" class="form-control">
                        </div>
                        <div class="col-2">
                            <input type="number" class="form-control">
                        </div>
                        <div class="col-2">
                            <button class="btn btn-danger">X</button>
                        </div>                        
                    </div>
                </div>
            </div>
        </form>
    </div>
</div>

Kemudian buka file recipe-edit.component.ts, hal yang akan dilakukan adalah

  • Menambahkan property form.
  • Inject Recipe Service.
  • Membuat method untuk inisialisasi form.
import { Component, OnInit } from '@angular/core';
//import lib FormGroup jika tidak ditambahkan  otomatis oleh IDE.
import { FormControl, FormGroup } from '@angular/forms';
import { ActivatedRoute, Params } from '@angular/router';
import { RecipeService } from '../recipe.service';

@Component({
  selector: 'app-recipe-edit',
  templateUrl: './recipe-edit.component.html',
  styleUrls: ['./recipe-edit.component.css']
})
export class RecipeEditComponent implements OnInit {
  id! : number;
  editMode = false;
  //property untuk menyimpan informasi Form
  recipeForm! : FormGroup;

  constructor(private route: ActivatedRoute, private recipeSrv : RecipeService) { }

  ngOnInit(): void {
    this.route.params.subscribe(
      (params : Params) =>{
        this.id = +params['id'];
        this.editMode = params['id'] != null;
        //jalankan fungsi initForm.
        this.initForm();
      }
    );
  }

  //method untuk inisialisasi form
  private initForm(){
    let recipeNm = '';
    let recipeImg = '';
    let recipeDesc = '';

    if (this.editMode){
      const recipe = this.recipeSrv.getRecipe(this.id);
      recipeNm = recipe.name;
      recipeImg = recipe.imgPath;
      recipeDesc = recipe.description;
    }
    this.recipeForm = new FormGroup({
      'name': new FormControl(recipeNm),
      'imgPath': new FormControl(recipeImg),
      'description': new FormControl(recipeDesc)
    });
  }

  //method handling form onsubmit.
  onSubmit(){
    console.log(this.recipeForm);
  }
}

SInkronisasi Form

Berikutnya kita akan lakukan sinkronisasi antara template dengan typescript code. Sengaja kami buat dalam tahap terpisah agar lebih jelas proses penggunaan reactive form.

Buka file recipe-edit.component.html, kita akan tambahkan beberapa code yaitu:

  • Directive formGroup pada form agar dikenali Angular form akan dihandle manual via typescript.
  • Directive formControlName pada element input.
  • Event listener untuk form submit.
<div class="row">
    <div class="col-xs-12">
        <!-- directive formGroup dan submit listener -->
        <form [formGroup]="recipeForm" (ngSubmit)="onSubmit()">
            <div class="row">
                <div class="col-12">
                    <button type="submit" class="btn btn-success">Save</button>
                    <button type="submit" class="btn btn-danger">Cancel</button>
                </div>
            </div>
            <div class="row">
                <div class="col-12">
                    <div class="form-group">
                        <label for="name">Name</label>
                        <!-- tambahkan directive formControlName -->
                        <input type="text" class="form-control" id="name" formControlName="name">
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-12">
                    <div class="form-group">
                        <label for="imgPath">Image URL</label>
                        <!-- tambahkan directive formControlName -->
                        <input type="text" class="form-control" id="imgPath" formControlName="imgPath">
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-12">
                    <img src="" class="img-fluid.">
                </div>
            </div>            
            <div class="row">
                <div class="col-12">
                    <div class="form-group">
                        <label for="description">Description</label>
                        <!-- tambahkan directive formControlName -->
                        <textarea class="form-control" id="description" rows="5" formControlName="description"></textarea>
                    </div>
                </div>
            </div>
            <div class="row mt-2">
                <div class="col-12">
                    <div class="row">
                        <div class="col-8">
                            <input type="text" class="form-control">
                        </div>
                        <div class="col-2">
                            <input type="number" class="form-control">
                        </div>
                        <div class="col-2">
                            <button class="btn btn-danger">X</button>
                        </div>                        
                    </div>
                </div>
            </div>
        </form>
    </div>
</div>

Jika dijalankan sesuai ekspektasi, implementasi reactive form berhasil.

Saat kita tambahkan new recipe dan submit form, data dari form sudah berhasil kita akses.

Begitu juga saat kita tampilkan recipe yang sudah ada kedalam form.

Pada modul berikutnya kita akan menghandle data ingredient.

Sharing is caring:

Leave a Comment