Angular Tutorial: Consume REST API using HttpClient Example

by Didin J. on Mar 11, 2023 Angular Tutorial: Consume REST API using HttpClient Example

A comprehensive step-by-step Angular HttpClient or HTTP service tutorial on consuming REST API from the remote server

A comprehensive tutorial of the Angular HttpClient or HTTP Service that use for consuming REST API service from the remote server. Angular HttpClient is one of the fundamental features of Angular. We expect that you learn this tutorial by following a walkthrough of a working Angular application example. So, this will straight be forwarded to the usage or implementation of Angular HttpClient.

Table of contents:

In this walkthrough tutorial, we will show you how to access external or remote REST API services using this Angular HttpClient. For now, we will use existing Node.js, Express.js, and MongoDB RESTful API from our GitHub repository, or if you have PostgreSQL installed on your machine, you can get this REST API application. After this, the HttpClient feature will show you in an easy way and a little bit different from the original Angular docs.

The following tools, frameworks, and modules are required to complete this Angular tutorial:

  1. Node.js (Recommended version)
  2. Angular
  3. Angular-CLI
  4. Node.js/Express MongoDB
  5. Terminal (Mac/Linux) or Node Command Line (Windows)
  6. IDE or Text Editor

We assume that you have downloaded and installed the Node.js environment. Now, let's check the above requirement by opening the terminal or Node command line and then going to your projects folder. Type this command to check the latest Node and NPM versions.

node -v
v18.14.0
npm -v
9.5.1

That's our Node and NPM versions, before moving to the main steps of the Angular HttpClient tutorial, you will get the walkthrough in real practice in this silent Video tutorial. Not all, but it's practicable. Don't forget to like, share, comment, and subscribe to our Youtube channel.


Install/Update Angular CLI and Create Angular HttpClient Web Application

The Angular CLI is a tool to initialize, develop, scaffold, and maintain Angular applications. To install or upgrade the latest Angular CLI, type this command in the terminal or Node command line.

npm install -g @angular/cli

Next, create a new Angular Web Application using this Angular CLI command.

ng new angular-httpclient

If there are questions to add routing, just press the "y" key and use "SCSS" as a stylesheet format.

? Would you like to add Angular routing? (y/N) Yes
? Which stylesheet format would you like to use? 
  CSS 
❯ SCSS   [ https://sass-lang.com/documentation/syntax#scss                ] 
  Sass   [ https://sass-lang.com/documentation/syntax#the-indented-syntax ] 
  Less   [ http://lesscss.org                                             ] 
  Stylus [ http://stylus-lang.com                                         ] 

Next, go to the newly created Angular project folder.

cd ./angular-httpclient

Now, you run the new Angular web application using your own host and port.

ng serve --host 0.0.0.0 --port 8080

Open your browser then go to `localhost:8080` you will see this Angular page.

Angular Tutorial: Consume REST API using HttpClient Example - welcome

Next, we will be working with IDE or Text Editor for this tutorial. To use Visual Studio Code, type this command under this Angular web app folder after you stopped the running Angular app by pressing CTRL+C.

code .


Setup Local JSON File or Remote REST API Service

For this tutorial, we will use one of the Local JSON files or the remote REST API service that will consume or call by Angular HttpClient. For local JSON files, simply, create a new folder inside `src/assets`.

mkdir src/assets/data
touch src/assets/data/smartphone.json

Open and edit `src/assets/data/smartphone.json` then add these lines of JSON data.

[
  {
    "id": "P0001",
    "name": "iPhone X",
    "desc": "iPhone X 128GB Internal Memory, 8GB RAM, 6 Inch IPS Display",
    "price": 499,
    "updated": "Wed Sep 20 2019 17:22:41 GMT+0700"
  },
  {
    "id": "P0002",
    "name": "iPhone 11 Pro",
    "desc": "Super Retina XDR display, 5.8‑inch (diagonal) all‑screen OLED Multi‑Touch display, HDR display, 2436‑by‑1125-pixel resolution at 458 ppi 2,000,000:1 contrast ratio (typical)",
    "price": 699,
    "updated": "Wed Sep 20 2019 17:22:41 GMT+0700"
  },
  {
    "id": "P0003",
    "name": "iPhone XR",
    "desc": "Liquid Retina HD display 6.1-inch (diagonal) all-screen LCD Multi-Touch display with IPS technology 1792-by-828-pixel resolution at 326 ppi 1400:1 contrast ratio (typical)",
    "price": 599,
    "updated": "Wed Sep 20 2019 17:22:41 GMT+0700"
  }
]

Now, the local JSON file is ready to use with your Angular HttpClient. Next, to prepare the remote REST API, we already have the source codes and tutorials for you with MongoDB or PostgreSQL.

Node.js, Express.js, and MongoDB https://github.com/didinj/node-express-mongodb-restapi.git

Make sure you have installed the required database (MongoDB) then you can clone that Node-Express REST API server and run it from your local machine.


Setup and Configure Angular HttpClient

In the created Angular web application, we will set up and configure Angular HttpClient. The modules are already included with Angular, we just register the module for use within the Angular web application. Open and edit `src/app/app.module.ts` then add this import of Angular Common HTTP HttpClientModule.

import { HttpClientModule } from '@angular/common/http';

Add that module in `@NgModule` imports.

  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule,
  ],

That it's, now you can use the Angular HttpClient in your application.


Create Angular Service with Angular HttpClient Error Handling

We will put HttpClient access to the separate Angular service. For that, type this command to generate an Angular service after stopping the running Angular application by pressing `CTRL+C`.

ng g service rest

Next, open and edit `src/app/rest.service.ts` then add these HttpClient, HttpHeaders, HttpErrorResponse, Observable, RxJS, and RxJS Operators imports.

import { catchError } from 'rxjs/internal/operators';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { map } from 'rxjs/operators';

Inject the HttpClient module to the constructor params.

constructor(private http: HttpClient) { }

Declare the variable for the RESTAPI endpoint before the @Injectable annotation.

const endpoint = 'http://localhost:3000/api/v1/';

Error Handling

Next, add a function to handle the error at the bottom of the class body.

  private handleError(error: HttpErrorResponse): any {
    if (error.error instanceof ErrorEvent) {
      console.error('An error occurred:', error.error.message);
    } else {
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    return throwError(() => 'Something bad happened; please try again later.');
  }

Another way to handle the error is by using HttpInterceptor. To do that, create a new folder `src/app/interceptors`, and an HttpErrorInterceptor file.

mkdir src/app/interceptors
touch src/app/interceptors/HttpErrorInterceptor.ts

Next, open and edit `src/app/interceptors/HttpErrorInterceptor.ts` then add these imports of RxJS Observable, throwError, catchError, tap, Angular Common Http HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, and HttpErrorResponse.

import { catchError, tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';

Add these Typescript class that intercepts error from the HttpRequest.

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request)
      .pipe(
        tap(data => console.log(data)),
        catchError((error: HttpErrorResponse) => {
          if (error.error instanceof ErrorEvent) {
            // A client-side or network error occurred. Handle it accordingly.
            console.error('An error occurred:', error.error.message);
          } else {
            // The backend returned an unsuccessful response code.
            // The response body may contain clues as to what went wrong,
            console.error(
              `Backend returned code ${error.status}, ` +
              `body was: ${error.error}`);
          }
          // return an observable with a user-facing error message
          return throwError(() => 'Something bad happened; please try again later.');
        })
      );
  }
}

Next, open and edit `src/app/app.module.ts` then add or update this import of Angular Common Http HttpInterceptor and HttpErrorInterceptor that were previously created.

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpErrorInterceptor } from './interceptors/HttpErrorInterceptor';

Add them to the @NgModule provider's array.

providers: [
  {
    provide: HTTP_INTERCEPTORS,
    useClass: HttpErrorInterceptor,
    multi: true,
  }
],

You can use the Retry function to retry the HttpRequest after an error is occurred to make sure the HTTP request is a real error. Add this function after the pipe function inside HttpErrorInterceptor or service function.

getSmartphone(): Observable<any> {
  return this.http.get<Smartphone[]>(localUrl).pipe(
    retry(3), catchError(this.handleError<Smartphone[]>('getSmartphone', [])));
}

Don't forget to modify the existing RxJS import.

import {catchError, retry} from 'rxjs/internal/operators';


Basic Local JSON or RESP API Request Example

We will put all JSON requests in the Angular Service that was previously created. Declare a constant variable before the @Injectable that holds the local URL of the JSON file.

const localUrl = 'assets/data/smartphone.json';

You change the URL of your REST API server if you are using remote REST API. Add a function below the constructor to get the data from the JSON file.

getSmartphone() {
  return this.http.get(localUrl);
}

Now, you can access the JSON call from the Angular component. Open and edit `src/app/app.component.ts` then add or modify these imports of Angular OnInit and ApiService.

import { Component, OnInit } from '@angular/core';
import { RestService } from './rest.service';

Inject the ApiService to the constructor.

constructor(private api: RestService) {}

Add a variable before the constructor that holds the response from the data subscription.

smartphone: any[] = [];

Add a new function to subscribe to data that emits from the ApiService then put it to an array variable that was previously declared with the specific fields.

getSmartphones() {
  this.api.getSmartphone()
    .subscribe(data => {
      for (const d of (data as any)) {
        this.smartphone.push({
          name: d.name,
          price: d.price
        });
      }
      console.log(this.smartphone);
    });
}

If you run the app now, you can see the array of data in the browser console that returned from the ApiService like this.

(3) [{…}, {…}, {…}]
0: {name: "iPhone X", price: 499}
1: {name: "iPhone 11 Pro", price: 699}
2: {name: "iPhone XR", price: 599}
length: 3

The previous function uses a blind (any) type for the response of the subscribed data and returns the only array of data as shown in the JSON file. Now, we will show you to use a type and full response which includes special headers or status codes to indicate certain conditions that are important to the application workflow. We can create a new file to declare those fields of type or directly create an export interface of the type in the same component file. For this example, we will use a separate Typescript file.

touch src/app/smartphone.ts

Next, open and edit `src/app/smartphone.ts` then add these lines of type fields as the exported interface.

export interface Smartphone {
  id: string;
  name: string;
  desc: string;
  price: number;
  updated: Date;
}

Next, back to the service then add or modify these imports.

import { HttpClient, HttpResponse } from '@angular/common/http';
import { Smartphone } from './smartphone';
import { Observable } from 'rxjs';

Change the GET data function to this function.

getSmartphone(): Observable<HttpResponse<Smartphone[]>> {
  return this.http.get<Smartphone[]>(
    localUrl, { observe: 'response' });
}

Next, back to the component then add this import of the above type interface.

import { Smartphone } from './smartphone';

Change the variable type from any to Smartphone type.

  smartphone: Smartphone[] = [];
  headers: any;
  spresp: any;
  postdata: Smartphone | undefined;

Modify the function that calls the ApiService.

  getSmartphones() {
    this.api.getSmartphone()
    .subscribe(resp => {
      console.log(resp);
      const keys = resp.headers.keys();
      this.headers = keys.map((key: any) =>
        `${key}: ${resp.headers.get(key)}`);
  
      for (const data of resp.body!) {
        this.smartphone.push(data);
      }
      console.log(this.smartphone);
    });
  }

Now, you will see the full response.

HttpResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://localhost:4200/assets/data/smartphone.json", ok: true, …}body: (3) [{…}, {…}, {…}]headers: HttpHeaders {normalizedNames: Map(7), lazyUpdate: null, lazyInit: null, headers: Map(7)}ok: truestatus: 200statusText: "OK"type: 4url: "http://localhost:4200/assets/data/smartphone.json"__proto__: HttpResponseBase

To GET data by ID simply add this function to the Rest service.

  getSmartphoneById(id: any): Observable<any> {
    return this.http.get<Smartphone>(localUrl + id).pipe(
      retry(3), catchError(this.handleError));
  }

In the component add this function.

getSmartphoneById(id: any) {
  this.api.getSmartphoneById(id)
    .subscribe(data => {
      console.log(data);
    });
}


Angular HTTPHeaders

Almost every HTTP request including headers. Sometimes, REST API servers required additional header parameters on every request. For example, the secured REST API endpoint is only accessible with an Authorization header token, the specific REST API request uses a different type of response by determining the type from the HTTP headers. To add the header to this HttpClient example, in the ApiService file add or modify this import of @angular/common/http HttpHeaders.

import { HttpHeaders } from '@angular/common/http';

Add a constant variable before the @Injectable that determines the HttpHeaders parameters.

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type':  'application/xml',
    'Authorization': 'jwt-token'
  })
};

Add that httpOptions to the required HTTP request. In this example, modify the existing GET request.

  getSmartphone(): Observable<any> {
    return this.http.get<Smartphone[]>(localUrl, httpOptions).pipe(
      retry(3), catchError(this.handleError));
  }

The HTTP request headers will look like this.

GET /assets/data/smartphone.json HTTP/1.1
Host: localhost:4200
Connection: keep-alive
Accept: application/json, text/plain, */*
Authorization: jwt-token
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
Sec-Fetch-Mode: cors
Content-Type: application/json
Sec-Fetch-Site: same-origin
Referer: http://localhost:4200/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,id;q=0.8
Cookie: _ga=GA1.1.257623774.1563284797; __atuvc=63%7C35%2C22%7C36%2C7%7C37%2C7%7C38%2C4%7C39
If-None-Match: W/"341-9uZs5GFl2K0WHOI2X11xYKnJlvM"

Because the instance of HttpHeaders class is immutable, we can modify HttpHeaders values directly.

  getSmartphone(): Observable<any> {
    httpOptions.headers = httpOptions.headers.set('Authorization', 'my-new-auth-token');
    return this.http.get<Smartphone[]>(localUrl, httpOptions).pipe(
      retry(3), catchError(this.handleError));
  }

And here's the headers change.

...
Authorization: my-new-auth-token
...


Add REST API CRUD Operation to Angular Service

The CRUD operation implements the HTTP POST, GET, PUT, and DELETE methods. In the rest.service.ts file, we will put all CRUD operation which has typed or non-typed response.

Non-Typed Response

For non-typed-response, add this function after the constructor to extract it.

  private extractData(res: Response): any {
    const body = res;
    return body || { };
  }

Add a function to GET product data from the REST API using HttpClient then subscribe to the response to RxJS Observable.

  getProducts(): Observable<any> {
    return this.http.get(endpoint + 'products').pipe(
      map(() => this.extractData),
      catchError(this.handleError)
    );
  }

Similar to the above function, this time GET product data by ID.

  getProduct(id: string): Observable<any> {
    return this.http.get(endpoint + 'products/' + id).pipe(
      map(() => this.extractData),
      catchError(this.handleError)
    );
  }

Typed Response

For typed responses, add a new interface after the imports for mapping the response fields.

export interface Product {
  _id: string;
  prod_name: string;
  prod_desc: string;
  prod_price: number;
  updated_at: Date;
}

Add the functions of getting product list and product by ID.

  getProducts(): Observable<any> {
    return this.http.get<Product>(endpoint + 'products').pipe(
      catchError(this.handleError)
    );
  }

  getProduct(id: string): Observable<any> {
    return this.http.get<Product>(endpoint + 'products/' + id).pipe(
      catchError(this.handleError)
    );
  }

Add a function to POST new product data to the REST API using Angular HttpClient then subscribe to the response to RxJS Observable. This is an Angular POST example in the Angular service.

  addProduct(product: any): Observable<any> {
    return this.http.post(endpoint + 'products', product).pipe(
      catchError(this.handleError)
    );
  }

Add a function to PUT an updated product data by ID to the REST API using HttpClient then subscribe to the response to RxJS Observable.

  updateProduct(id: string, product: Product): Observable<any> {
    return this.http.put<Product>(endpoint + 'products/' + id, product).pipe(
      catchError(this.handleError)
    );
  }

Add a function to DELETE product by ID to the REST API using Angular HttpClient then subscribe to the response to RxJS Observable.

  deleteProduct(id: string): Observable<any> {
    return this.http.delete<Product>(endpoint + 'products/' + id).pipe(
      catchError(this.handleError)
    );
  }

The above functions show a complete RESTAPI CRUD operation such as GET, POST, PUT, and DELETE.  Simply as that, the main function of the Angular HttpClient. Next, we add the component for simple access to the Angular service.


Accessing Angular HttpClient Service from Component

Now, we have to access all RESTAPI Service calls that use Angular HttpClient from the component. For that, add or generate all required components using these commands.

ng g component product
ng g component product-add
ng g component product-detail
ng g component product-edit

Open and edit `src/app/app.module.ts` then add an import of the Angular FormsModule.

import { FormsModule } from '@angular/forms';

Add that module to the @NgModule imports.

  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule,
    FormsModule,
  ],

Next, open and edit `src/app/app-routing.module.ts` then add these imports of the generated components.

import { ProductComponent } from './product/product.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { ProductAddComponent } from './product-add/product-add.component';
import { ProductEditComponent } from './product-edit/product-edit.component';

Replace the routes constant with this.

const routes: Routes = [
  {
    path: 'products',
    component: ProductComponent,
    data: { title: 'Product List' }
  },
  {
    path: 'product-details/:id',
    component: ProductDetailComponent,
    data: { title: 'Product Details' }
  },
  {
    path: 'product-add',
    component: ProductAddComponent,
    data: { title: 'Product Add' }
  },
  {
    path: 'product-edit/:id',
    component: ProductEditComponent,
    data: { title: 'Product Edit' }
  },
  { path: '',
    redirectTo: '/products',
    pathMatch: 'full'
  }
];

Next, open and edit `src/app/app.component.html` then remove all tags except this tag.

<router-outlet></router-outlet>

Next, open and edit `src/app/product/product.component.ts` then replace all codes with this.

import { Component, OnInit } from '@angular/core';
import { RestService, Product } from '../rest.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-product',
  templateUrl: './product.component.html',
  styleUrls: ['./product.component.scss']
})
export class ProductComponent implements OnInit {

  products: Product[] = [];

  constructor(
    public rest: RestService,
    private router: Router) { }

  ngOnInit(): void {
    this.getProducts();
  }

  getProducts(): void {
    this.rest.getProducts().subscribe({
      next: (resp) => {
        this.products = resp;
        console.log(this.products);
      },
      error: (e) => {
        console.log(e);
      },
      complete: () => console.info('complete')
    });
  }

  add(): void {
    this.router.navigate(['/product-add']);
  }

  delete(id: string): void {
    this.rest.deleteProduct(id).subscribe({
      next: () => {
        this.getProducts();
      },
      error: (e) => {
        console.log(e);
      },
      complete: () => console.info('complete')
    });
  }

}

Open and edit `src/app/product/product.component.html` then replace all HTML tags with this Angular *ngFor iteration to iterate the products list.

<h2>Product List</h2>

<div>
  <button (click)="add()">
    Add
  </button>
</div>

<ul class="products">
  <li *ngFor="let p of products; let i=index;">
    <a routerLink="/product-details/{{p._id}}">
      <span class="badge">{{i+1}}</span> {{p.prod_name}}
    </a>
    <button class="delete" title="delete product"
      (click)="delete(p._id)">x</button>
  </li>
</ul>

Open and edit `src/app/product/product.component.scss` then replace all CSS syntax with this.

/* Products Component's private CSS styles */
.products {
  margin: 0 0 2em 0;
  list-style-type: none;
  padding: 0;
  width: 15em;
}
.products li {
  position: relative;
  cursor: pointer;
  background-color: #EEE;
  margin: .5em;
  padding: .3em 0;
  height: 1.6em;
  border-radius: 4px;
}

.products li:hover {
  color: #607D8B;
  background-color: #DDD;
  left: .1em;
}

.products a {
  color: #888;
  text-decoration: none;
  position: relative;
  display: block;
  width: 250px;
}

.products a:hover {
  color:#607D8B;
}

.products .badge {
  display: inline-block;
  font-size: small;
  color: white;
  padding: 0.8em 0.7em 0 0.7em;
  background-color: #607D8B;
  line-height: 1em;
  position: relative;
  left: -1px;
  top: -4px;
  height: 1.8em;
  min-width: 16px;
  text-align: right;
  margin-right: .8em;
  border-radius: 4px 0 0 4px;
}

button {
  background-color: #eee;
  border: none;
  padding: 5px 10px;
  border-radius: 4px;
  cursor: pointer;
  cursor: hand;
  font-family: Arial;
}

button:hover {
  background-color: #cfd8dc;
}

button.delete {
  position: relative;
  left: 194px;
  top: -32px;
  background-color: gray !important;
  color: white;
}

And here are the rest of the components codes.

`src/app/product-add/product-add.component.ts`

import { Component, OnInit, Input } from '@angular/core';
import { RestService } from '../rest.service';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'app-product-add',
  templateUrl: './product-add.component.html',
  styleUrls: ['./product-add.component.scss']
})
export class ProductAddComponent implements OnInit {

  @Input() productData = { prod_name: '', prod_desc: '', prod_price: 0 };

  constructor(public rest: RestService, private route: ActivatedRoute, private router: Router) { }

  ngOnInit(): void {
    // init here
  }

  addProduct(): void {
    this.rest.addProduct(this.productData).subscribe({
      next: (result) => {
        this.router.navigate(['/product-details/' + result._id]);
      },
      error: (e: any) => {
        console.log(e);
      }
    });
  }

}

`src/app/product-add/product-add.component.html`

<div>
  <h2>Product Add</h2>
  <div>
    <label>Product Name:
      <input [(ngModel)]="productData.prod_name" placeholder="Product Name"/>
    </label><br>
    <label>Product Desc:
      <input [(ngModel)]="productData.prod_desc" placeholder="Product Description"/>
    </label><br>
    <label>Product Price:
      <input [(ngModel)]="productData.prod_price" placeholder="Product Price"/>
    </label><br>
  </div>
  <button (click)="addProduct()">Save</button>
</div>

`src/app/product-detail/product-detail.component.ts`

import { Component, OnInit } from '@angular/core';
import { RestService, Product } from '../rest.service';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'app-product-detail',
  templateUrl: './product-detail.component.html',
  styleUrls: ['./product-detail.component.scss']
})
export class ProductDetailComponent implements OnInit {

  product: Product | undefined;

  constructor(public rest: RestService, private route: ActivatedRoute, private router: Router) { }

  ngOnInit(): void {
    this.rest.getProduct(this.route.snapshot.params['id']).subscribe(
      (data: Product) => this.product = { ...data }
    );
  }

}

`src/app/product-detail/product-detail.component.html`

<div *ngIf="product" class="products">
  <h2>{{product.prod_name | uppercase}} Details</h2>
  <div><span>Description: </span>{{product.prod_desc}}</div>
  <div><span>Price: </span>{{product.prod_price}}</div>
  <div><span>Update Date: </span>{{product.updated_at | date}}</div>
  <div>
    <button routerLink="/product-edit/{{product._id}}">
      Edit
    </button>
  </div>
</div>

`src/app/product-edit/product-edit.component.ts`

import { Component, OnInit, Input } from '@angular/core';
import { RestService } from '../rest.service';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'app-product-edit',
  templateUrl: './product-edit.component.html',
  styleUrls: ['./product-edit.component.scss']
})
export class ProductEditComponent implements OnInit {

  @Input() productData: any = { prod_name: '', prod_desc: '', prod_price: 0 };

  constructor(public rest: RestService, private route: ActivatedRoute, private router: Router) { }

  ngOnInit(): void {
    this.rest.getProduct(this.route.snapshot.params['id']).subscribe((data: {}) => {
      console.log(data);
      this.productData = data;
    });
  }

  updateProduct(): void {
    this.rest.updateProduct(this.route.snapshot.params['id'], this.productData).subscribe({
      next: (result) => {
        this.router.navigate(['/product-details/' + result._id]);
      },
      error: (e) => {
        console.log(e);
      },
      complete: () => console.info('complete')
    });
  }

}

`src/app/product-edit/product-edit.component.html`

<div>
  <h2>Product Edit</h2>
  <div>
    <label>Product Name:
      <input [(ngModel)]="productData.prod_name" placeholder="Product Name"/>
    </label><br>
    <label>Product Desc:
      <input [(ngModel)]="productData.prod_desc" placeholder="Product Description"/>
    </label><br>
    <label>Product Price:
      <input [(ngModel)]="productData.prod_price" placeholder="Product Price"/>
    </label><br>
  </div>
  <button (click)="updateProduct()">Update</button>
</div>


Run and Test Angular HttpClient Web Application

Before running the Angular HttpClient application, run the REST API server first. We use our Express.js/MongoDB RESTful application, so open the other tabs to run the MongoDB server and Express.js server.

mongod
nodemon

Next, type this command in the current Terminal tabs to run the Angular 6 HttpClient application.

ng serve --open

You should enable CORS to make the RESTAPI server accessible from different server ports. And here our Angular HttpClient Web application looks like.

Angular Tutorial: Consume REST API using HttpClient Example - edit

Angular Tutorial: Consume REST API using HttpClient Example - details

Angular Tutorial: Consume REST API using HttpClient Example - add

Angular Tutorial: Consume REST API using HttpClient Example - list

That it's, an example of Angular HttpClient RESTAPI service consumption. You can get the full source code on our GitHub.

If you don’t want to waste your time design your own front-end or your budget to spend by hiring a web designer then Angular Templates is the best place to go. So, speed up your front-end web development with premium Angular templates. Choose your template for your front-end project here.

That just the basic. If you need more deep learning about Angular and Typescript, you can take the following cheap course:

Thanks!