Today I am going to discuss how you can interact with REST API services to load and manage data.
Prerequisites
Before getting started, you need to have the below software installed on your development machine:
• Node.js and npm. You can install both of them from the Node.js
• Angular CLI (You can install it from npm using: npm install -g @angular/cli)
Frontend applications needs to call backend services over http/https protocol to manage dynamic data. Best place to access data from backend APIs are service component. Once you defined your service class you can inject it in to component or another service to use the service methods.
Angular provides the HttpClient service class in @angular/common/http module to interact with backend REST API services.
Using HttpClient request call you can easily handle your response and you can intercept your request and response. By intercepting the request, you can inject your security token or any other requested headers to all the service inside the one place. By intercepting the response, you can handle all the errors in a single place. I will explain interceptor concept in another chapter with more details.
Today we will check how you can use HttpClient methods to do get data from service API. Get method of HTTP Client returns RxJS observable type and you can subscribe to the RxJS observable inside the component where you call the service method.
If you look at my flower store code in GitHub, you can see I have hard coded flower objects and put them into an array as below.
mySellingFlowers(){
let rose = new flower();
rose.name = "Rose";
rose.price = 100;
rose.availableQuantity = 1000;
rose.isChecked = false;
this. myFlowerList.push(rose);
let lily = new flower();
lily.name = "Lilly";
lily.price = 80;
lily.availableQuantity = 2000;
lily.isChecked = false;
this. myFlowerList.push(lily);
let tulip = new flower();
tulip.name = "Tulip";
tulip.price = 100;
tulip.availableQuantity = 2300;
lily.isChecked = false;
this. myFlowerList.push(tulip);
let carnation = new flower();
carnation.name = "Carnation";
carnation.price = 50;
carnation.availableQuantity = 1500;
lily.isChecked = false;
this. myFlowerList.push(carnation);
let gerbera = new flower();
gerbera.name = "Gerbera";
gerbera.price = 50;
gerbera.availableQuantity = 1500;
lily.isChecked = false;
this. myFlowerList.push(gerbera);
let orchid = new flower();
orchid.name = "Orchid";
orchid.price = 50;
orchid.availableQuantity = 1500;
lily.isChecked = false;
this. myFlowerList.push(orchid);
}
Today we will check how you can read flowers from backend REST API call. I am planning to use designer.mocky.io to mock my API call. To access list of flowers through API and to read it from Angular side that API should return an JOSN array. Therefor I will make a JSON array to define a response in my mock API as below.
{"flowers":[
{"name":"Rose", "price":"100", "availableQuantity":"1000","isChecked":false},
{"name":"Lilly", "price":"80", "availableQuantity":"2000","isChecked":false},
{"name":"Tulip", "price":"100", "availableQuantity":"2300","isChecked":false},
{"name":"Carnation", "price":"80", "availableQuantity":"1500","isChecked":false},
{"name":"Gerbera", "price":"50", "availableQuantity":"1500","isChecked":false},
{"name":"Orchid", "price":"200", "availableQuantity":"1500","isChecked":false}
]
}
]}
ng g s flower
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class FlowerService {
constructor() { }
}
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class FlowerService {
constructor(private http:HttpClient) {}
getFlowerList():Observable<any>{
return this.http.get('https://run.mocky.io/v3/cee1c6e9-1491-4191-9054-ce7df1c1a500');
}
}
constructor(private flowerService:FlowerService) { }
I have commented out my array with hard coded data and add the below codes to read data from service method.
this.flowerService.getFlowerList().subscribe(response=>{
this.myFlowerList = response.flowers
},
err => console.error(err),
() => console.log('done loading foods')
)
I have added full code for landing component for you to refer.
import { Component, EventEmitter, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { flower } from '../../domain/flower';
import { DataService } from 'src/app/services/data.service';
import { FlowerService } from 'src/app/services/flower.service';
@Component({
selector: 'app-landing',
templateUrl: './landing.component.html',
styleUrls: ['./landing.component.scss'],
})
export class LandingComponent implements OnInit {
myFlowerList:flower[]=[];
selectedFlowers: string[] =[];
checkedList:string[]=[];
searchText:string='';
constructor(private dataService:DataService, private flowerService:FlowerService) { }
ngOnInit() {
this.mySellingFlowers();
this.dataService.getSearchText().subscribe(response => {
this.printSearchtext(response);
})
}
printSearchtext(searchText){
this.searchText = searchText;
}
printOrder(flowerName){
if(this.selectedFlowers.indexOf(flowerName)<0){
this.selectedFlowers.push(flowerName)
}
else{
let index = this.selectedFlowers.indexOf(flowerName);
this.selectedFlowers.splice(index,1);
}
}
mySellingFlowers(){
// let rose = new flower();
// rose.name = "Rose";
// rose.price = 100;
// rose.availableQuantity = 1000;
// rose.isChecked = false;
// this. myFlowerList.push(rose);
// let lily = new flower();
// lily.name = "Lilly";
// lily.price = 80;
// lily.availableQuantity = 2000;
// lily.isChecked = false;
// this. myFlowerList.push(lily);
// let tulip = new flower();
// tulip.name = "Tulip";
// tulip.price = 100;
// tulip.availableQuantity = 2300;
// lily.isChecked = false;
// this. myFlowerList.push(tulip);
// let carnation = new flower();
// carnation.name = "Carnation";
// carnation.price = 50;
// carnation.availableQuantity = 1500;
// lily.isChecked = false;
// this. myFlowerList.push(carnation);
// let gerbera = new flower();
// gerbera.name = "Gerbera";
// gerbera.price = 50;
// gerbera.availableQuantity = 1500;
// lily.isChecked = false;
// this. myFlowerList.push(gerbera);
// let orchid = new flower();
// orchid.name = "Orchid";
// orchid.price = 50;
// orchid.availableQuantity = 1500;
// lily.isChecked = false;
// this. myFlowerList.push(orchid);
this.flowerService.getFlowerList().subscribe(response=>{
this.myFlowerList = response.flowers
},
err => console.error(err),
() => console.log('done loading foods')
)
}
trackFlowers(index,flower){
return flower?flower.name:undefined
}
}
<div *ngFor="let flower of myFlowerList;trackBy:trackFlowers">
<flower-card [title]="flower.name" (selectedFlower)="printOrder($event)"></flower-card>
</div>
To use the Angular HttpClient, we need to inject it into our app's dependencies in app.module.ts file as below.
imports: [
BrowserModule,
AppRoutingModule,
CardModule,
CheckboxModule,
CommonModule,
FormsModule,
InputTextModule,
HttpClientModule
],
Unless it gives you below error.
core.js:7187 ERROR Error: Uncaught (in promise): NullInjectorError: StaticInjectorError(AppModule)[HttpClient]:
StaticInjectorError(Platform: core)[HttpClient]:
NullInjectorError: No provider for HttpClient!
NullInjectorError: StaticInjectorError(AppModule)[HttpClient]:
I have added app.module.ts file code after adding the dependency and you can check full code to the app by accessing GitHub.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LandingComponent } from './modules/landing/landing.component';
import { HomeComponent } from './modules/home/home.component';
import { CardModule } from 'primeng/card';
import {CheckboxModule} from 'primeng/checkbox';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {InputTextModule} from 'primeng/inputtext';
import { FlowerCardComponent } from './modules/cards/flower-card/flower-card.component';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent,
LandingComponent,
HomeComponent,
FlowerCardComponent
],
imports: [
BrowserModule,
AppRoutingModule,
CardModule,
CheckboxModule,
CommonModule,
FormsModule,
InputTextModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Once you load the app it will show same data as before by getting the data from backend API call.
Comments
Post a Comment