Pada modul ini kita akan melakukan form submit.
Untuk kesederhanaan tutorial, data yang diterima dari form akan ditambahkan pada array recipe. Pada praktek real aplikasi, tentu akan disimpan kedalam database.
Untuk menambahkan data kedalam array, kita perlu tambahkan method save pada recipe service.
Selain itu kita perlu menambahkan Subject sebagai event listener ketika isi recipe berubah.
Buka file recipe.service.ts
import { Injectable } from "@angular/core";
//tambahkan library subject jika IDE tidak otomatis menambahkannya
import { Subject } from "rxjs";
import { Ingredient } from "../shared/ingredient.model";
import { ShoppingListService } from "../shopping-list/shopping-list.service";
import { Recipe } from "./recipe.model";
@Injectable()
export class RecipeService{
//tambahkan subject untuk perubahan recipe
recipeChange = new Subject<Recipe[]>();
private recipes: Recipe[] = [
new Recipe(
'Oreo Dorayaki 1',
'Doriyaki dengan bahan utama Oreo',
'https://i.ytimg.com/vi/nJGmdqb892Y/maxresdefault.jpg',
[
new Ingredient('Oreo', 1),
new Ingredient('Susu', 1),
]),
new Recipe(
'Oreo Dorayaki 2',
'Doriyaki dengan bahan utama Oreo 2',
'https://i.ytimg.com/vi/nJGmdqb892Y/maxresdefault.jpg',
[
new Ingredient('Oreo', 1),
new Ingredient('Gula', 1),
])
];
constructor (private shoppingListServ: ShoppingListService){}
getRecipes(){
return this.recipes.slice();
}
getRecipe(idx : number){
return this.recipes[idx];
}
addIngToShopList(ingredients : Ingredient[]){
this.shoppingListServ.addIngredients(ingredients);
}
// tambahkan method add dan update recipe
addRecipe(recipe: Recipe){
this.recipes.push(recipe);
this.recipeChange.next(this.recipes.slice());
}
updRecipe(idx: number, updRecipe: Recipe){
this.recipes[idx] = updRecipe;
this.recipeChange.next(this.recipes.slice());
}
}
Kemudian buka recipe-edit.component.ts, pada method onSubmit, ubah code menjadi memanggil method dari service untuk melakukan update atau add recipe.
import { Component, OnInit } from '@angular/core';
import { FormArray, FormControl, FormGroup, Validators } 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;
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;
this.initForm();
}
);
}
private initForm(){
let recipeNm = '';
let recipeImg = '';
let recipeDesc = '';
let recipeIngredients = new FormArray([]);
if (this.editMode){
const recipe = this.recipeSrv.getRecipe(this.id);
recipeNm = recipe.name;
recipeImg = recipe.imgPath;
recipeDesc = recipe.description;
if (recipe['ingredients']){
for (let ing of recipe.ingredients){
recipeIngredients.push(
new FormGroup({
'name' : new FormControl(ing.name, Validators.required),
'amount' : new FormControl(ing.amount, [Validators.required, Validators.pattern(/^[1-9]+[0-9]*$/)])
})
);
}
}
}
this.recipeForm = new FormGroup({
'name': new FormControl(recipeNm, Validators.required),
'imgPath': new FormControl(recipeImg, Validators.required),
'description': new FormControl(recipeDesc, Validators.required),
'ingredients': recipeIngredients
});
}
onAddIngredient(){
(<FormArray>this.recipeForm.get('ingredients')).push(
new FormGroup({
'name': new FormControl(),
'amount' : new FormControl()
})
);
}
//tambahkan code untuk memanggil method add atau update recipe dari recipe service
onSubmit(){
if (this.editMode){
this.recipeSrv.updRecipe(this.id, this.recipeForm.value);
}else{
this.recipeSrv.addRecipe(this.recipeForm.value);
}
}
get ingredientsCtrl(){
return (<FormArray>this.recipeForm.get('ingredients')).controls;
}
}
Terakhir, jangan lupa untuk melakukan subscribe terhadap perubahan isi recipe. Buka file recipe-list.component.ts, lalu tambahkan code pada ngOnInit
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Recipe } from '../recipe.model';
import { RecipeService } from '../recipe.service'; // RecipeService
@Component({
selector: 'app-recipe-list',
templateUrl: './recipe-list.component.html',
styleUrls: ['./recipe-list.component.css']
})
export class RecipeListComponent implements OnInit {
recipes!: Recipe[];
constructor(private recipeService: RecipeService,
private router: Router,
private route: ActivatedRoute
) { }
ngOnInit(): void {
//subscribe perubahan recipe
this.recipeService.recipeChange.subscribe(
(recipes: Recipe[])=>{
this.recipes = recipes;
}
);
this.recipes = this.recipeService.getRecipes();
}
onNewRecipe(){
this.router.navigate(['new'], {relativeTo: this.route});
}
}
