Angular 8 CRUD is a basic operation to learn Angular from scratch. We will learn how to build a small web application that inserts, read data, update and delete data from the database. You will learn how to create a MEAN Stack web application. In this Angular 8 Tutorial Example, you will learn a new framework by building a crud application.

New features of Angular 8

You check out the new features in brief on my Angular 8 New Features post.

I have designed this Angular 8 CRUD Tutorial, especially for newcomers, and it will help you to up and running with the latest version of Angular, which is right now 8.

The workflow of Angular crud example

We will create two separate projects. One is for Angular Frontend, and one is for Node.js and Express. That means one for frontend and one for the backend.

We will create the backend API, which deals with storing, modifying, and deleting the form values, and the frontend will consume that API; for example, it shows the data from the backend.

For this example, I am using the following tech stacks with their versions.

Node v11.3.0 NPM v6.9.0 AngularCLI v8.0.1 MongoDB shell version v3.6.3 MongoDB version v3.6.3 Mac OS Mojave

In this blog, I have previously written Angular 7 CRUD and Angular 6 CRUD tutorials in deep. Now, the Angular community has released the next version, which is Angular 8.

If you do not know how to upgrade Angular CLI to version 8, then check out my Angular CLI 8 upgrade tutorial. In this MEAN Stack tutorial, we will see Angular Routing, Angular Forms, and on the back end side, we use Node.js and Express.js to handle the data and to store the data, we will use MongoDB.

Angular 8 CRUD Example

If you are looking to find a tutorial on how to build crud application in Angular 8 and mean stack app then continue this post. This post is a comprehensive guide to take you a tour where you will learn how to send a network requests to node server, how to handle the response, how to display data in the frontend, and so on. The post is lengthy but stay with me it is gonna be a hell lot of fun.

We will use Node.js as a platform and Express.js, which is a web framework built on top of Node.js, and MongoDB as a NoSQL Database.

But, you will learn more concepts like project structure, modules, dependency injection, service, components, routing, http requests, and much more. It is like you will learn almost half the framework by doing this project.

In this tutorial, we will use the Angular 8. So if you are not so sure what Angular CLI version you are using, then type the following command, which will tell us the Angular CLI version.

ng --version

Angular 8 sample project description

We will create a demo project, where a user can save their ProductName, Product Description, and ProductPrice from the Angular form and submit the form to the node.js server.

If the values are incorrect, then it will validate at the frontend, and the form will not submit.

We will not validate the field values at the backend because it will make this tutorial more lengthy. If you want to create a validation at the backend, then check out my express form validation tutorial.

If all the values are perfect, then it will send the form values to the Node.js backend API, and it will store the values inside the MongoDB database.

Our Angular 8 CRUD Tutorial will be very long so please bear with me for this long journey.

Step 1: Create Angular 8 project

Let’s create an Angular 8 project using the following command.

When you install a brand new Angular project, see the options they are providing while creating a new project. In this project, we need the routing module, so we will allow the Angular CLI to create a routing module for us.

I am using Visual Studio Code as a programming editor to develop Angular application.

Now, go inside the folder and open the project inside the VSCode.

cd angular8tutorial code .

At the time of installation, we have enabled routing for our angular app. You can check the file called app-routing.module.ts file inside the src >> app directory.

Next, install the Bootstrap 4 CSS Framework using the following command. It is not a necessary step, and you can choose your CSS Framework as well.

npm install bootstrap --save

Now, add it inside an angular.json file.

"styles": [ "src/styles.css", "./node_modules/bootstrap/dist/css/bootstrap.min.css" ],

It will include a bootstrap CSS file, and we can use the bootstrap classes inside any file.

Start an Angular development server using the following command.

ng serve -o

The server starts at the http://localhost:4200/. You can see the output in the browser. It is an initial Angular home screen.

Step 2: Create Angular components

Hit the following command to generate the Angular Components. We will perform to create, read, update operations. So we will create three components.

ng g c product-add --skipTests=true ng g c product-get --skipTests=true ng g c product-edit --skipTests=true

Option “spec” is deprecated in Angular 8: Use “skipTests” instead.

For this demo, we do not need the tests file. So, we will not create it.

All the three components are automatically registered inside an app.module.ts file. Now, we need to configure the routing of angular components inside an app-routing.module.ts file.

Now, you can see an app-routing.module.ts file inside the src >> app folder file. It is created because while we were installing the angular app, we permitted angular cli to generate the routing file for us.

All the three components are automatically registered inside an app.module.ts file. Now, we need to import and configure the routing of angular components inside the app-routing.module.ts file.

Write the following code inside an app-routing.module.ts file.

// app-routing.module.ts import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { ProductAddComponent } from './product-add/product-add.component'; import { ProductEditComponent } from './product-edit/product-edit.component'; import { ProductGetComponent } from './product-get/product-get.component'; const routes: Routes = [ { path: 'product/create', component: ProductAddComponent }, { path: 'edit/:id', component: ProductEditComponent }, { path: 'products', component: ProductGetComponent } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }

Now, you can see inside the app.component.html file that <router-outlet> directive is there. This directive helps us to render the different components based on route URI.

Step 3: Create Angular 8 Routing

Write the following code inside the app.component.html file.

<nav class="navbar navbar-expand-sm bg-light"> <div class="container-fluid"> <ul class="navbar-nav"> <li class="nav-item"> <a routerLink="product/create" class="nav-link" routerLinkActive="active"> Create Product </a> </li> <li class="nav-item"> <a routerLink="products" class="nav-link" routerLinkActive="active"> Products </a> </li> </ul> </div> </nav> <div class="container"> <router-outlet></router-outlet> </div>

Save the file and go to the browser and click on two links. You can see that we can see the different components based on navigation.

Step 4: Configure Angular routing progress indicator.

Type the following command to install the ng2-slim-loading-bar library.

npm install ng2-slim-loading-bar --save

So, if you install the third-party packages right now, then it is not compatible with an Angular 8. If we want to bridge the gap between Angular 8 and the third-party packages, we need to install the following library. That is it.

npm install rxjs-compat --save

Now, import the SlimLoadingBarModule inside an app.module.ts file.

// app.module.ts import { SlimLoadingBarModule } from 'ng2-slim-loading-bar'; imports: [ ... SlimLoadingBarModule ],

The next step is, include the styling that comes with the library inside src >> styles.css file.

@import "../node_modules/ng2-slim-loading-bar/style.css";

Step 5: Add Angular router events.

Angular RouterModule gives us the following event modules.

NavigationStart NavigationEnd NavigationError NavigationCancel Router Event

Now, write the following code inside the app.component.ts file.

// app.component.ts import { Component } from '@angular/core'; import {SlimLoadingBarService} from 'ng2-slim-loading-bar'; import { NavigationCancel, Event, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'angular8tutorial'; constructor(private loadingBar: SlimLoadingBarService, private router: Router) { this.router.events.subscribe((event: Event) => { this.navigationInterceptor(event); }); } private navigationInterceptor(event: Event): void { if (event instanceof NavigationStart) { this.loadingBar.start(); } if (event instanceof NavigationEnd) { this.loadingBar.complete(); } if (event instanceof NavigationCancel) { this.loadingBar.stop(); } if (event instanceof NavigationError) { this.loadingBar.stop(); } } }

In the above code, we have told the Angular 8 application that while we navigate from one component to another component, while we want to display the router progress indicator.

When a user clicks the other route, the angular progress indicator start showing, and when the navigation is complete, it will stop displaying. So, it is a kind of best User experience for the user.

What it is doing in the code that it intercepts the routing event and adds the loading bar component to the loading route so that we can see the routing indication every time we change the routes.

The final change is to display the routing indicator is that we need to insert an ng2-slim-loading-bar directive inside the app.component.html file at the top of the page.

<!-- app.component.html --> <ng2-slim-loading-bar color="blue"></ng2-slim-loading-bar> <nav class="navbar navbar-expand-sm bg-light"> <div class="container-fluid"> <ul class="navbar-nav"> <li class="nav-item"> <a routerLink="product/create" class="nav-link" routerLinkActive="active"> Create Product </a> </li> <li class="nav-item"> <a routerLink="products" class="nav-link" routerLinkActive="active"> Products </a> </li> </ul> </div> </nav> <div class="container"> <router-outlet></router-outlet> </div>

Save the file and go to the terminal to see if there any error, and if there is no error, then go to the browser and change the routes, and you can see that now we can see the routing indicator while changing the different angular routes.

Step 6: Add bootstrap 4 to HTML form

Inside the product-add.component.html file, add the following bootstrap 4 form. We have three HTML fields for this demo.

<!-- product-add.component.html --> <div class="card"> <div class="card-body"> <form> <div class="form-group"> <label class="col-md-4">Product Name</label> <input type="text" class="form-control" /> </div> <div class="form-group"> <label class="col-md-4">Product Description </label> <textarea class="form-control" rows = 7 cols = "5"></textarea> </div> <div class="form-group"> <label class="col-md-4">Product Price</label> <input type="text" class="form-control" /> </div> <div class="form-group"> <button type="submit" class="btn btn-primary">Create Product</button> </div> </form> </div> </div>

Step 7: Create Angular 8 form validation

For form validation, we have two options. Template-based and Reactive Forms Module. We will use the ReactiveFormsModule approach. Now, if you are new to Angular Form Validation, then please check out my this article Angular Form Validation Example Tutorial on this blog.

Now, import the ReactiveFormsModule inside the app.module.ts file. It comes with an Angular project by default.

// app.module.ts import { ReactiveFormsModule } from '@angular/forms'; imports: [ ... ReactiveFormsModule ],

Now, we need to write a code for the app.component.ts file. Remember, this is not the template-driven form. So we need to add the code inside the app.component.ts file.

First, we import the FormGroup, FormBuilder, Validators modules from @angular/forms.

Also, create a constructor and instantiate the FormBuilder.

So write the following code inside the product-add.component.ts file.

// product-add.component.ts import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; @Component({ selector: 'app-product-add', templateUrl: './product-add.component.html', styleUrls: ['./product-add.component.css'] }) export class ProductAddComponent implements OnInit { angForm: FormGroup; constructor(private fb: FormBuilder) { this.createForm(); } createForm() { this.angForm = this.fb.group({ ProductName: ['', Validators.required ], ProductDescription: ['', Validators.required ], ProductPrice: ['', Validators.required ] }); } ngOnInit() { } }

We have used a form builder to handle all the validation. So in that constructor, we are creating the form with all the validation rules for particular fields. In our example, there are three fields.

If the input text is empty, then it will give an error, and we need to display that error.

Now, write the following code inside the product-add.component.html file.

<!-- product-add.component.html --> <div class="card"> <div class="card-body"> <form [formGroup]="angForm" novalidate> <div class="form-group"> <label class="col-md-4">Product Name</label> <input type="text" class="form-control" formControlName="ProductName" #ProductName /> </div> <div *ngIf="angForm.controls['ProductName'].invalid && (angForm.controls['ProductName'].dirty || angForm.controls['ProductName'].touched)" class="alert alert-danger"> <div *ngIf="angForm.controls['ProductName'].errors.required"> Product Name is required. </div> </div> <div class="form-group"> <label class="col-md-4">Product Description </label> <textarea class="form-control" rows = 7 cols = "5" formControlName="ProductDescription" #ProductDescription></textarea> </div> <div *ngIf="angForm.controls['ProductDescription'].invalid && (angForm.controls['ProductDescription'].dirty || angForm.controls['ProductDescription'].touched)" class="alert alert-danger"> <div *ngIf="angForm.controls['ProductDescription'].errors.required"> Product Description is required. </div> </div> <div class="form-group"> <label class="col-md-4">Product Price</label> <input type="text" class="form-control" formControlName="ProductPrice" #ProductPrice /> </div> <div *ngIf="angForm.controls['ProductPrice'].invalid && (angForm.controls['ProductPrice'].dirty || angForm.controls['ProductPrice'].touched)" class="alert alert-danger"> <div *ngIf="angForm.controls['ProductPrice'].errors.required"> Product Price is required. </div> </div> <div class="form-group"> <button type="submit" class="btn btn-primary" [disabled]="angForm.pristine || angForm.invalid" > Create Product </button> </div> </form> </div> </div>

Save the file and go to the browser, and you can see if you do not put any value inside the input box, then you will see the errors.

Step 8: Add and configure the HttpClientModule

Most front-end applications communicate with the backend services over an HTTP protocol. Modern browsers support the two different APIs for making HTTP requests: the XMLHttpRequest interface and the fetch API.

The HttpClient in @angular/common/http offers a simplified client HTTP API for Angular applications that rests on the XMLHttpRequest interface exposed by browsers.

Additional benefits of the HttpClient include the testability features, typed request and response objects, request and response interception, the Observables APIs, and smooth error handling.

Import the HttpClientModule inside an app.module.ts file.

// app.module.ts import { HttpClientModule } from '@angular/common/http'; imports: [ ... HttpClientModule ],

Step 9: Create a typescript model file.

Inside the src >> app folder, create one file called Product.ts and add the following code.

// Product.ts export default class Product { ProductName: string; ProductDescription: string; ProductPrice: number; }

Step 10: Create Angular Service file.

Type the following command to generate the service file.

The primary use of the service file is that we are adding all of our AJAX code inside that file. So, it sends an ajax request to the backend server and retrieves the data from the backend server.

ng g service products --skipTests=true

So, your necessary products.service.ts file looks like this.

// products.service.ts import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class ProductsService { constructor() { } }

Now, import the products.service.ts file into the app.module.ts file.

// app.module.ts import { ProductsService } from './products.service'; providers: [ ProductsService ],

Step 11: Submit form values to node server

Now, we need to write the code that will send the HTTP POST request with the data to the Node.js server and store the data into the MongoDB database.

Write the following code inside the products.service.ts file.

// products.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class ProductsService { uri = 'http://localhost:4000/products'; constructor(private http: HttpClient) { } addProduct(ProductName, ProductDescription, ProductPrice) { const obj = { ProductName, ProductDescription, ProductPrice }; console.log(obj); this.http.post(`${this.uri}/add`, obj) .subscribe(res => console.log('Done')); } }

We have defined our backend API URL, but we have not created any backend yet, but we will do it in the following couple of steps.

Now, we need to add the click event to the Add Product Button. So add the following code inside a product-add.component.html file.

<div class="form-group"> <button (click) = "addProduct(ProductName.value, ProductDescription.value, ProductPrice.value)" type="submit" class="btn btn-primary" [disabled]="angForm.pristine || angForm.invalid" > Create Product </button> </div>

So when there are no errors, we can submit the form, and it will call the component’s addPropduct function. From there, we will call the angular service, and the service will send the HTTP Post request to the Node.js server.

Now, add the addProduct function inside the product-add.component.ts file. So write the following code inside the product-add.component.ts file.

// product-add.component.ts import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { ProductsService } from '../products.service'; @Component({ selector: 'app-product-add', templateUrl: './product-add.component.html', styleUrls: ['./product-add.component.css'] }) export class ProductAddComponent implements OnInit { angForm: FormGroup; constructor(private fb: FormBuilder, private ps: ProductsService) { this.createForm(); } createForm() { this.angForm = this.fb.group({ ProductName: ['', Validators.required ], ProductDescription: ['', Validators.required ], ProductPrice: ['', Validators.required ] }); } addProduct(ProductName, ProductDescription, ProductPrice) { this.ps.addProduct(ProductName, ProductDescription, ProductPrice); } ngOnInit() { } }

In the above code, first, I have imported the products.service.ts file. Then we have defined the addProduct method.

This method is called when the user clicks on the create product button, and the flow will transfer over here. We get the ProductName, ProductDescription, and ProductPrice data inside the addProduct function.

Inside that function, we are calling the products.service.ts file’s addProduct function and pass the three parameters with it.

So, from the products.service.ts file will call the API and save the products on the server. Now, we need to configure the backend API.

Up until now, we have reached half of this Angular 8 CRUD example.

In the next half, we will talk about Node, Express, MongoDB, API, and stuff because this tutorial is Angular 8 CRUD Full Stack Example.

Step 12: Create a backend API in Node

Inside the angular root folder, create one folder called the API and go inside that folder. Remember, it will be a completely separate project from the Angular frontend project.

So its node_modules folders are different from the Angular project.

Open a terminal inside the API folder and type the following command. It will generate the package.json file using NPM. We do not want to specify each option one by one; that is why we are typing the following command.

npm init -y

Install the following node-specific modules.

npm install express body-parser cors mongoose --save

I do not want to restart the node server each time; I change the file. So I am installing the nodemon server. What it does is that, when I modify a server.js file, it restarts a node.js server automatically.

npm install nodemon --save-dev

We are also installing the body-parser module to parse the data from the incoming Http request.

We have installed the CORS module because our both angular and node application is running on the different ports.

The browser will not allow the CROSS REQUEST ORIGIN attack; that is why we need to install the CORS module to receive the proper request at the backend server.

We have installed the Mongoose module because it provides the ORM for the MongoDB database.

Now, inside the API folder, create one file called server.js file. Add the following code inside that file.

// server.js const express = require('express'), path = require('path'), bodyParser = require('body-parser'), cors = require('cors'), mongoose = require('mongoose'); const app = express(); let port = process.env.PORT || 4000; const server = app.listen(function(){ console.log('Listening on port ' + port); });

The next thing is to connect the MongoDB database with our node express application.

If you have not installed a MongoDB database, then install it and then start the MongoDB server using the following command.

mongod

So, Now, I have connected to a database.

Create one file called DB.js inside the api root project folder. Write the following code inside a DB.js file.

// DB.js module.exports = { DB: 'mongodb://localhost:27017/ng8crud' };

Import this DB.js file inside our server.js file and use the Mongoose library to set up the database connection with MongoDB. We can also use the Mongoose to save the data in the database using the Mongoose ORM.

Write the following code inside a server.js file to connect our MongoDB application to a Node.js server.

// server.js const express = require('express'), path = require('path'), bodyParser = require('body-parser'), cors = require('cors'), mongoose = require('mongoose'), config = require('./DB'); mongoose.Promise = global.Promise; mongoose.connect(config.DB, { useNewUrlParser: true }).then( () => {console.log('Database is connected') }, err => { console.log('Can not connect to the database'+ err)} ); const app = express(); app.use(bodyParser.json()); app.use(cors()); const port = process.env.PORT || 4000; const server = app.listen(port, function(){ console.log('Listening on port ' + port); });

Save the above server.js file and go to the terminal and start the node server using the following command. Remember, we are using nodemon.

nodemon server

So, right now, you have three servers running.

Angular Development Server for frontend. Nodemon server for the backend. MongoDB server for database.

Remember, all three servers are running fine without any error; otherwise, our application will not work, and it will crash.

Step 13: Create a route and model files.

Now, we need to create two folders inside the api root folder called routes and models.

In the models’ folder, create one model called Product.js.

// Product.js const mongoose = require('mongoose'); const Schema = mongoose.Schema; // Define collection and schema for Product let Product = new Schema({ ProductName: { type: String }, ProductDescription: { type: String }, ProductPrice: { type: Number } },{ collection: 'Product' }); module.exports = mongoose.model('Product', Product);

So, we have defined our schema for the Product collection. We have three fields called ProductName, ProductDescription, ProductPrice.

In the routes folder, create one file called the product.route.js.

Write the CRUD code inside the product.route.js file.

// product.route.js const express = require('express'); const app = express(); const productRoutes = express.Router(); // Require Product model in our routes module let Product = require('../models/Product'); // Defined store route productRoutes.route('/add').post(function (req, res) { let product = new Product(req.body); product.save() .then(product => { res.status(200).json({'Product': 'Product has been added successfully'}); }) .catch(err => { res.status(400).send("unable to save to database"); }); }); // Defined get data(index or listing) route productRoutes.route('/').get(function (req, res) { Product.find(function (err, products){ if(err){ console.log(err); } else { res.json(products); } }); }); // Defined edit route productRoutes.route('/edit/:id').get(function (req, res) { let id = req.params.id; Product.findById(id, function (err, product){ res.json(product); }); }); // Defined update route productRoutes.route('/update/:id').post(function (req, res) { Product.findById(req.params.id, function(err, product) { if (!product) res.status(404).send("Record not found"); else { product.ProductName = req.body.ProductName; product.ProductDescription = req.body.ProductDescription; product.ProductPrice = req.body.ProductPrice; product.save().then(product => { res.json('Update complete'); }) .catch(err => { res.status(400).send("unable to update the database"); }); } }); }); // Defined delete | remove | destroy route productRoutes.route('/delete/:id').get(function (req, res) { Product.findByIdAndRemove({_id: req.params.id}, function(err, product){ if(err) res.json(err); else res.json('Successfully removed'); }); }); module.exports = productRoutes;

Here, we have used the mongoose model to save, update, delete the data from the database. Mongoose is an ORM used in the MongoDB database. It will handle all the CRUD task at the backend. Now, we have all the CRUD operations functions set up on the route file. The final thing is that we need to import inside the server.js file.

Remember, the server.js file is the starting point of our backend node application. So every module needs to be included inside the server.js file.

So, our final server.js file looks like this.

// server.js const express = require('express'), path = require('path'), bodyParser = require('body-parser'), cors = require('cors'), mongoose = require('mongoose'), config = require('./DB'); const productRoute = require('./routes/product.route'); mongoose.Promise = global.Promise; mongoose.connect(config.DB, { useNewUrlParser: true }).then( () => {console.log('Database is connected') }, err => { console.log('Can not connect to the database'+ err)} ); const app = express(); app.use(bodyParser.json()); app.use(cors()); app.use('/products', productRoute); const port = process.env.PORT || 4000; const server = app.listen(port, function(){ console.log('Listening on port ' + port); });

Now, go to the terminal and start the node server if you have not already started.

#Step 14: Save data in MongoDB database

If all of your servers are up and running, then you can go to the browser and fill the form data and add the Product. You can see something like this on your screen if you are successful.

Sometimes, if you are running an adblocker on the browser, then it will not work. So please turn off the adblocker and try this example again.

Now, we can check on the database using the following commands.

First, open the mongo shell on the 4th tab because all the other three tabs are occupied at the moment.

mongo

Here, we can see that the values are storing in the MongoDB database. Yess!! We have succeeded.

Now, remaining operations are Read, Update, and Delete.

#Step 15: Show the data on Angular Frontend

We can iterate the backend data and display the data in the tabular format using Angular ngfor directive.

Inside the product-get.component.html file, write the following code.

<!-- product-get.component.html --> <table class="table table-hover"> <thead> <tr> <td>Product Name</td> <td>Product Description</td> <td>Product Price</td> <td colspan="2">Actions</td> </tr> </thead> <tbody> <tr *ngFor="let product of products"> <td>{{ product.ProductName }}</td> <td>{{ product.ProductDescription }}</td> <td>{{ product.ProductPrice }}</td> <td><a [routerLink]="['/edit', product._id]" class="btn btn-primary">Edit</a></td> <td><a [routerLink]="" class="btn btn-danger">Delete</a></td> </tr> </tbody> </table>

Now, inside the products.service.ts file, we need to write the function that fetches the product data from the MongoDB database and display it at the Angular application.

// products.service.ts getProducts() { return this .http .get(`${this.uri}`); }

In the above getProducts() function, we have sent the HTTP GET request to the Node.js server and fetch the data from the database.

Now, we need to include the products.service.ts file and Product.ts file inside a product-get.component.ts file.

Write the following code inside the product-get.component.ts file.

// product-get.component.ts import { Component, OnInit } from '@angular/core'; import Product from '../Product'; import { ProductsService } from '../products.service'; @Component({ selector: 'app-product-get', templateUrl: './product-get.component.html', styleUrls: ['./product-get.component.css'] }) export class ProductGetComponent implements OnInit { products: Product[]; constructor(private ps: ProductsService) { } ngOnInit() { this.ps .getProducts() .subscribe((data: Product[]) => { this.products = data; }); } }

Save the file and go to the browser and switch to this URL: http://localhost:4200/products. You can see the listing of the products.

Okay, first, we need to fetch the data from the MongoDB database using _id wise and display that data in the product-edit.component.html file.

For that, when the product-edit.component.html loads, we send an AJAX request to the node server and fetch the particular row using the _id and display the data to their respective fields inside the HTML form.

So first, write the following code inside the product-edit.component.ts file.

// product-edit.component.ts import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { ProductsService } from '../products.service'; @Component({ selector: 'app-product-edit', templateUrl: './product-edit.component.html', styleUrls: ['./product-edit.component.css'] }) export class ProductEditComponent implements OnInit { angForm: FormGroup; product: any = {}; constructor(private route: ActivatedRoute, private router: Router, private ps: ProductsService, private fb: FormBuilder) { this.createForm(); } createForm() { this.angForm = this.fb.group({ ProductName: ['', Validators.required ], ProductDescription: ['', Validators.required ], ProductPrice: ['', Validators.required ] }); } ngOnInit() { this.route.params.subscribe(params => { this.ps.editProduct(params['id']).subscribe(res => { this.product = res; }); }); } }

Here, when the product-edit component.ts render, it will call the ngOnInit method and send an HTTP request to the node server and fetch the data from an _id to display inside the product-edit component.html file.

Now, inside the products.service.ts file, we need to code the editProduct function to send an HTTP request.

// products.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class ProductsService { uri = 'http://localhost:4000/products'; constructor(private http: HttpClient) { } addProduct(ProductName, ProductDescription, ProductPrice) { console.log(ProductName, ProductDescription, ProductPrice); const obj = { ProductName, ProductDescription, ProductPrice }; this.http.post(`${this.uri}/add`, obj) .subscribe(res => console.log('Done')); } getProducts() { return this .http .get(`${this.uri}`); } editProduct(id) { return this .http .get(`${this.uri}/edit/${id}`); } }

Now, finally, we need to write the form inside the product-edit.component.html file.

<!-- product-edit.component.html --> <div class="card"> <div class="card-body"> <form [formGroup]="angForm" novalidate> <div class="form-group"> <label class="col-md-4">Product Name</label> <input type="text" class="form-control" formControlName="ProductName" #ProductName [(ngModel)] = "product.ProductName"/> </div> <div *ngIf="angForm.controls['ProductName'].invalid && (angForm.controls['ProductName'].dirty || angForm.controls['ProductName'].touched)" class="alert alert-danger"> <div *ngIf="angForm.controls['ProductName'].errors.required"> Product Name is required. </div> </div> <div class="form-group"> <label class="col-md-4">Product Description </label> <textarea class="form-control" rows = 7 cols = "5" formControlName="ProductDescription" #ProductDescription [(ngModel)] = "product.ProductDescription"></textarea> </div> <div *ngIf="angForm.controls['ProductDescription'].invalid && (angForm.controls['ProductDescription'].dirty || angForm.controls['ProductDescription'].touched)" class="alert alert-danger"> <div *ngIf="angForm.controls['ProductDescription'].errors.required"> Product Description is required. </div> </div> <div class="form-group"> <label class="col-md-4">Product Price</label> <input type="text" class="form-control" formControlName="ProductPrice" #ProductPrice [(ngModel)] = "product.ProductPrice" /> </div> <div *ngIf="angForm.controls['ProductPrice'].invalid && (angForm.controls['ProductPrice'].dirty || angForm.controls['ProductPrice'].touched)" class="alert alert-danger"> <div *ngIf="angForm.controls['ProductPrice'].errors.required"> Product Price is required. </div> </div> <div class="form-group"> <button (click) = "updateProduct(ProductName.value, ProductDescription.value, ProductPrice.value)" type="submit" class="btn btn-primary" [disabled]="angForm.invalid" > Update Product </button> </div> </form> </div> </div>

Save the file and go to the listing page and click on the edit button and you will see the populated form fields from the database.

You can also see the warning like the following. Ignore this demo tutorial.

forms.js:1193

It looks like you’re using ngModel on the same form field as formControlName.

Support for using the ngModel input property and ngModelChange event with

reactive form directives have been deprecated in Angular v6 and will be removed

in Angular v7.

Now, we need to update the data into the database.

Inside the products.service.ts file, we need to write a function that updates the form fields data. See the following code.