Building a Recipe Book app in Angular-4

Recipe

Welcome to part-4 of the recipe book app. We will start with adding forms in our app.

We will add on top of the app we have create in the previous part. You can find the code for the earlier part in this github link.

We will use the template driven approach in shopping edit component first. But we need to get rid of the local reference and click handler first in shopping-edit.component.html file.

shopping-edit.component.html

Now, as we are using template driven approach we will add the ngSubmit an ngForm in form. Beside this we are also adding name and ngModel in inout.

shopping-edit.component.html

One thing i noticed that we don’t have FormsModule included in app.module.ts file. So, we will include the same in it.

app.module.ts

Now, in shopping-edit.component.ts file we will first delete the ViewChild and earlier references.

shopping-edit.component.ts

Now, we will add the form in onSubmit method and use it’s value in newIngredient in shopping-edit.component.ts file.

shopping-edit.component.ts

We are now able to add items as usual in localhost.

localhost

We will now add validation in our form by adding required in name and amount. We are also adding a regular expression in amount to check, if the user cannot enter negative numbers.

After that we are adding disabled in the submit button in shopping-edit.component.html file.

shopping-edit.component.html

Now, the validations are working properly.

localhost

So, it’s time to make our items editable. We will first add a new function on the click handler in shopping-list.component.html file.

shopping-list.component.html

Next, in the shopping-list.service.ts file, we will add a new startedEditing EventEmitter and also add a new function getIngredient, to get a single ingredient.

shopping-list.service.ts

Now, in the shopping-list.component.ts file we will add the function onEditItem to emit the startedEditing.

shopping-list.component.ts

Finally, in the shopping-edit.component.ts file we will subscribe to the startedEditing and use setValue to set the name and amount.

shopping-edit.component.ts

Now, in localhost when we click on any item, we will get it filled in the input boxes.

localhost

Now, we will add the logic to update our form and for this, we will show Update or Add button based on editMode in shopping-edit.component.html file.

shopping-edit.component.html

Now, in the shopping-list.service.ts file, we will add a new function updateIngredient().

shopping-list.service.ts

Lastly in the shopping-edit.component.ts file, we will call updateIngredient or addIngredient, based on editMode.

shopping-edit.component.ts

Now, our edit logic is working properly in localhost.

localhost

Now, we will add the logic to reset the form and also the functionality to clear the entered fields. First add a function onClear in the Clear button in the shopping-edit.component.html file.

shopping-edit.component.ts

Next, in the shopping-edit.component.ts file add the form rest on the submit and also the onClear. We are also making the editMode as false in both.

shopping-edit.component.ts

Now, our form is resetting on clicking of Add/Update and the Clear button also working perfectly on localhost.

Next, we will work on the Delete button. We will add a deleteIngredient() first in shopping-list.service.ts file, which is using splice to delete the item.

shopping-list.service.ts

Next, we will add the onDelete() in shopping-edit.component.ts file, which is calling the deleteIngredient() first and then the onClear().

shopping-edit.component.ts

Lastly in shopping-edit.component.html file, we will add the click handler for Delete button.

shopping-edit.component.html

Now, our shopping list form is fully functional and working properly.

Shopping List

Now, we will move to recipe and will use the reactive approach to edit and delete a recipe. But first we will add the ReactiveFormsModule in app.module.ts file.

app.module.ts

Now, in the recipe-edit.component.ts file do some import which are required.

import { RecipeService } from '../recipe.service';
import { FormControl, FormGroup } from '@angular/forms';

Now, in the recipe-edit.component.ts file we will ad a function initForm(), which will create a new form with recipeName, recipeImagePath and recipeDescription.

We also have onSubmit, which is just console logging the form.

recipe-edit.component.ts

Our recipe-edit.component.html file was empty and we will put this basic code it in. It’s an HTML form with reactive controls.

<div class="row">
<div class="col-xs-12">
<form [formGroup]="recipeForm" (ngSubmit)="onSubmit()">
<div class="row">
<div class="col-xs-12">
<button type="submit" class="btn btn-success">Save</button>
<button type="button" class="btn btn-danger">Cancel</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" formControlName="name" class="form-control">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label for="imagePath">Image URL</label>
<input type="text" id="imagePath" formControlName="imagePath" class="form-control" >
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label for="description">Description</label>
<textarea type="text" id="description" class="form-control" formControlName="description"
rows="6"></textarea>
</div>
</div>
</div>
</form>
</div>
</div>

Now, when we click on Edit Recipe, it is working perfectly and also when we click on Add Recipe a blank form is been shown.

localhost

Now, we will add the logic to show the ingredients. For this in recipe-edit.component.ts file add the variable recipeIngredients which is a FormArray.

After this inside the editMode, we are checking whether the ingredients is ther and adding it to a FormGroup by looping through it. Lastly we are adding it to the recipeForm.

We are also adding a helper function of controls, which we are soon going to use in the template.

recipe-edit.component.ts

Now, in the recipe-edit.component.html file, we will add the row to show the ingredients. The ngFor here is using the helper function controls() from the typescript file.

recipe-edit.component.html

Now, the ingredients are also shown properly in localhost.

localhost

Now, we will add a button to add the Ingredients in our Edit recipe and for this we will add the code first in recipe-edit.component.html file. Here, we have a button with a click handler calling a function onAddIngredient().

recipe-edit.component.html

Now, we will add the function for the same in recipe-edit.component.ts file

recipe-edit.component.ts

Now, clicking on Add Ingredient in localhost will add the row for ingredients.

localhost

Now, we will add validations in our app. We need to add the validations mainly in the recipe-edit.component.ts file. We are mainly adding the required validator, but also adding the pattern validator in amount.

recipe-edit.component.ts

Now, in the recipe-edit.component.html file we will make the Save button disabled if the recipeForm is not valid.

recipe-edit.component.html

We are adding a bit of css in recipe-edit.component.css file to show red border in case of error.

recipe-edit.component.css

Now, if we don’t enter the fields we will get a red border.

red border

Now, we will add the logic to submit the form. For this we will first have two services addRecipe and updateRecipe in recipe.service.ts file.

recipe.service.ts

Now, in the recipe-list.components.ts file, we will add a subscriber to get the new recipe.

recipe-list.components.ts

Now, in the onSubmit(), in recipe-edit.component.ts file, we will call the updateRecipe or addRecipe based on editMode.

recipe-edit.component.ts

Now, in localhost we are able to add or update a recipe.

Add or update

Now, we will complete our delete button. First we need to add a deleteRecipe function in recipe.service.ts file.

recipe.service.ts

After that in the recipe-detail.component.html file, we will add a click handler for onDeleteRecipe().

recipe-detail.component.html

Lastly in the recipe-detail.component.ts file we will implement the function, which uses the deleteRecipe services to delete the recipe and also the router to navigate back to recipes.

recipe-detail.component.ts

Now, we will add the functionality for Cancel but. For it add a click handler first in recipe-edit.component.html file.

recipe-edit.component.html

Next, we will add the onCancel to the recipe-edit.component.ts file.

recipe-edit.component.ts

Now, we will add the image preview, while we Edit or Add a new recipe. So, in recipe-edit.component.html file first add a reference and then with it, we can show the image.

recipe-edit.component.html

Now, the preview of the image is working fine.

Preview

Now, we have a issue of adding a new recipe and navigation away to Shopping list component. Now the new recipe will disapear. This happens because because we have added the RecipeService in the recipes.component.ts file. So, we need to delete it from there.

recipes.component.ts

Now, we will add it in the app.module.ts file.

app.module.ts

Finally, we will add the functionalities to delete ingredients. First, add a click handler in recipe-edit.component.html file.

recipe-edit.component.html

Now, we will add it’s functionalities in recipe-edit.component.ts file.

recipe-edit.component.ts

Our long post is complete and we have almost completed the app. We will complete the app by adding HTTP functionalities in the last part.

Working

The code for this part can find in this github repo.

UI Lead- ReactJS, JavaScript and everything in-between.