We'll learn to create and consume RESTful APIs in Angular 8 project. ... to Receive and Delete the Data in Angular 8 HttpClient Service; Update Data in Angular CRUD App ... Which stylesheet format would you like to use?
Angular 8 HttpClient & Http tutorial is going to be discussed in this blog today. We’ll learn to create and consume RESTful APIs in Angular 8 project. To manage the data on the remote server, we make GET, POST, PUT and Delete using HttpClient API. We are required to import and setup HttpClient service in Angular 8 project to consume REST APIs.
To work with HttpClient service in Angular, you need to import the HttpClientModule
in app.module.ts
file. Then inject HttpClient service in constructor method after that you can hit the remote server via HTTP’s POST, GET, PUT and DELETE methods.
HttpClient API service is used to make communication between front-end web apps with backend services. This communication is done over HTTP protocol. Angular 8 HttpClient service makes the communication with remote server very easy. It needs to be imported via @angular/common/http package.
“HttpClient is available as an injectable class, with methods to perform HTTP requests. Each request method has multiple signatures, and the return type varies based on the signature that is called (mainly the values of observe and responseType).”
Angular 8 HttpClient MethodsIn the first step, We’ll set up the development environment in our system for setting up an Angular 8 project from scratch.
Follow this tutorial to set up Node JS in your system: How To Install Node JS?
Node JS will allow us to install the required packages for this Angular 8 HttpClient tutorial.
In the next step, we’ll be installing Angular CLI with the help of Node Package Manager (NPM).
npm install @angular/cli -gAngular 8 HttpClient & Http Tutorial – Build, Consume RESTful API
By Digamber Rawat Last updated on July 26, 2019
Angular 8 HttpClient & Http tutorial is going to be discussed in this blog today. We’ll learn to create and consume RESTful APIs in Angular 8 project. To manage the data on the remote server, we make GET, POST, PUT and Delete using HttpClient API. We are required to import and setup HttpClient service in Angular 8 project to consume REST APIs.
To work with HttpClient service in Angular, you need to import the HttpClientModule
in app.module.ts
file. Then inject HttpClient service in constructor method after that you can hit the remote server via HTTP’s POST, GET, PUT and DELETE methods.
HttpClient API service is used to make communication between front-end web apps with backend services. This communication is done over HTTP protocol. Angular 8 HttpClient service makes the communication with remote server very easy. It needs to be imported via @angular/common/http package.
“HttpClient is available as an injectable class, with methods to perform HTTP requests. Each request method has multiple signatures, and the return type varies based on the signature that is called (mainly the values of observe and responseType).”
Angular 8 HttpClient MethodsIn the first step, We’ll set up the development environment in our system for setting up an Angular 8 project from scratch.
Follow this tutorial to set up Node JS in your system: How To Install Node JS?
Node JS will allow us to install the required packages for this Angular 8 HttpClient tutorial.
In the next step, we’ll be installing Angular CLI with the help of Node Package Manager (NPM).
npm install @angular/cli -g
To create front-end of our demo app we need to install Angular 8 app. Run the below command in your terminal.
ng new angular8-httpclient-tutorial ? Would you like to add Angular routing? Yes ? Which stylesheet format would you like to use? CSS
Once your project is downloaded, then get into the project folder.
cd angular8-httpclient-tutorial
We’ll also install Bootstrap 4 UI library in Angular 8 project using given below command.
npm install bootstrap
To use the Bootstrap 4 ui components go to angular.json
file and replace the following code.
"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
]
Create components in Angular 8 app to manage the data.
# ng g component components/add-issue ng g component components/edit-issue ng g component components/issue-list
Run the following command to start the app.
ng serve03 – Set up Fake JSON Backend Server in Angular 8 App
We are going to create a fake backend server using json-server NPM module in our Angular 8 app. This module will allow us to communicate with the server we can send and receive the data locally.
Run the below command to set fake json-server
globally.
sudo npm install -g json-server
In the root folder of your Angular 8 project, create a folder by the name of backend
and also create a file by the name of database.json
. This file will have our fake JSON data.
mkdir backend && cd backend && touch database.json
In next step go to your database.json
file and add some fake data.
{
"bugtracking": [
{
"issue_name": "Table Improvement",
"issue_message": "Issue tracking is awesome because of collaboration",
"id": 1
},
{
"issue_name": "Tooltip Issue",
"issue_message": "Issue tracking is awesome because of collaboration",
"id": 2
}
]
}
Finally, we are done setting up a fake JSON server in our Angular 8 app, now run the command to start the fake JSON server.
json-server --watch backend/database.json {^_^}/ hi! Loading backend/database.json Done Resources http://localhost:3000/bugtracking Home http://localhost:3000 Type s + enter at any time to create a snapshot of the database Watching...
If you are getting this response in your terminal that means you are ready to send and receive data using HttpClient service in Angular 8.
Check out the below urls
Resources: http://localhost:3000/bugtracking
Home: http://localhost:3000
Angular 8 Front-end: http://localhost:4200
This service configures the dependency injector for HttpClient with supporting services for XSRF.
To make the HTTP request to communicate with the server, we first import the HttpClientModule
service in our Angular 8 app.
Go to app.module.ts
and paste the following code.
import { HttpClientModule } from '@angular/common/http';
Include the HttpClientModule in @NgModule's
imports array.
@NgModule({05 – Create Angular 8 Service to Consume RESTful APIs
imports: [
HttpClientModule
]
})
In the next step, we are going to create Angular 8 service file, this file will allow us to consume RESTful API. We’ll import HttpClient, HttpHeaders services to make the HTTP request work. We’ll create CRUD operations and also write some error handling logic in it.
But before we create the service file we need to create an interface class in which we’ll define the data type of our bug tracking demo app.
Create Bug class to define data type:
mkdir shared && cd shared
Create a bug.ts
file and paste the following code.
export class Bug {
id: string;
issue_name: string;
issue_message: string;
}
Create BugService Class, run the below command:
ng g s shared/bug
Now, paste the below code in bug.service.ts
file to create CRUD operation in our bug tracking app.
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Bug } from './bug';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';@Injectable({
providedIn: 'root'
})export class BugService {
// Base url
baseurl = 'http://localhost:3000';constructor(private http: HttpClient) { }
// Http Headers
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
}// POST
CreateBug(data): Observable<Bug> {
return this.http.post<Bug>(this.baseurl + '/bugtracking/', JSON.stringify(data), this.httpOptions)
.pipe(
retry(1),
catchError(this.errorHandl)
)
}// GET
GetIssue(id): Observable<Bug> {
return this.http.get<Bug>(this.baseurl + '/bugtracking/' + id)
.pipe(
retry(1),
catchError(this.errorHandl)
)
}// GET
GetIssues(): Observable<Bug> {
return this.http.get<Bug>(this.baseurl + '/bugtracking/')
.pipe(
retry(1),
catchError(this.errorHandl)
)
}// PUT
UpdateBug(id, data): Observable<Bug> {
return this.http.put<Bug>(this.baseurl + '/bugtracking/' + id, JSON.stringify(data), this.httpOptions)
.pipe(
retry(1),
catchError(this.errorHandl)
)
}// DELETE
DeleteBug(id){
return this.http.delete<Bug>(this.baseurl + '/bugtracking/' + id, this.httpOptions)
.pipe(
retry(1),
catchError(this.errorHandl)
)
}// Error handling
errorHandl(error) {
let errorMessage = '';
if(error.error instanceof ErrorEvent) {
// Get client-side error
errorMessage = error.error.message;
} else {
// Get server-side error
errorMessage =Error Code: ${error.status}\nMessage: ${error.message}
;
}
console.log(errorMessage);
return throwError(errorMessage);
}}
Then go to app.module.ts
file and import the Angular 8 service and inject into the providers array, like given below.
import { BugService } from 'shared/bug.service';06 – Make HTTP POST Request to Add the Data via HttpClient Service in Angular 8@NgModule({
declarations: [...],
imports: [...],
providers: [BugService],
bootstrap: [...]
})export class AppModule { }
Let’s add the data in local server using HttpClient service in Angular 8. Go to components > add-issue.component.ts
file and add the following code.
import { Component, OnInit, NgZone } from '@angular/core';
import { BugService } from '../../shared/bug.service';
import { FormBuilder, FormGroup } from '@angular/forms';
import { Router } from '@angular/router';@Component({
selector: 'app-add-issue',
templateUrl: './add-issue.component.html',
styleUrls: ['./add-issue.component.css']
})export class AddIssueComponent implements OnInit {
issueForm: FormGroup;
IssueArr: any = [];ngOnInit() {
this.addIssue()
}constructor(
public fb: FormBuilder,
private ngZone: NgZone,
private router: Router,
public bugService: BugService
){ }addIssue() {
this.issueForm = this.fb.group({
issue_name: [''],
issue_message: ['']
})
}submitForm() {
this.bugService.CreateBug(this.issueForm.value).subscribe(res => {
console.log('Issue added!')
this.ngZone.run(() => this.router.navigateByUrl('/issues-list'))
});
}}
Go to components > add-issue.component.html
file and add the following code.
<div class="container wrapper wrapper2">
<div class="row"><!-- Form --> <div class="col-md-12"> <h3>Add Issue</h3> <form [formGroup]="issueForm" (ngSubmit)="submitForm()" novalidate> <div class="form-group"> <label>Issue</label> <input type="text" formControlName="issue_name" class="form-control" maxlength="20"> </div> <div class="form-group"> <label>Issue Details</label> <textarea class="form-control" formControlName="issue_message" rows="3" maxlength="50"></textarea> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> </div>
</div>
Now, we can easily create an issue and save it to the local server using HttpClient and HttpHeaders Angular 8 services.
In this part of the tutorial, we are going to learn how to receive and delete the data via HttpClient API in an Angular CRUD app. We’ll use the Bootstrap 4 table to show the data on the frontend.
Go to components > issue-list.component.ts
file and paste the following code.
import { Component, OnInit } from '@angular/core';
import { BugService } from '../../shared/bug.service';@Component({
selector: 'app-issue-list',
templateUrl: './issue-list.component.html',
styleUrls: ['./issue-list.component.css']
})
export class IssueListComponent implements OnInit {IssuesList: any = [];
ngOnInit() {
this.loadEmployees();
}constructor(
public bugService: BugService
){ }// Issues list
loadEmployees() {
return this.bugService.GetIssues().subscribe((data: {}) => {
this.IssuesList = data;
})
}// Delete issue deleteIusse(data){ var index = index = this.IssuesList.map(x => {return x.issue_name}).indexOf(data.issue_name); return this.bugService.DeleteBug(data.id).subscribe(res => { this.IssuesList.splice(index, 1) console.log('Issue deleted!') }) }
}
Go to components > issue-list.component.html
file and paste the following code.
<div class="container wrapper">
<div class="row"><!-- Issue table --> <div class="col-md-12"> <div class="inner"> <h3>My Issues</h3> <table class="table table-bordered"> <thead> <tr> <th scope="col">#</th> <th scope="col">Issue Name</th> <th scope="col">Issue Details</th> <th scope="col">Action</th> </tr> </thead> <tbody> <tr *ngFor="let issues of IssuesList"> <th scope="row">{{issues.id}}</th> <td>{{issues.issue_name}}</td> <td>{{issues.issue_message}}</td> <td> <button type="button" class="btn btn-success btn-sm move-right" [routerLink]="['/edit-issue/', issues.id]">Edit</button> <button type="button" class="btn btn-danger btn-sm" (click)="deleteIusse(issues)">Remove</button> </td> </tr> </tbody> </table> </div> </div> </div>
</div>
In this final part of this tutorial, we are going to learn how to make PUT Request via HttpClient Angular 8 service to update the data on the server.
Head over to the components > edit-issue.component.ts
file and paste the following code.
import { Component, OnInit, NgZone } from '@angular/core';
import { BugService } from '../../shared/bug.service';
import { FormBuilder, FormGroup } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';@Component({
selector: 'app-edit-issue',
templateUrl: './edit-issue.component.html',
styleUrls: ['./edit-issue.component.css']
})export class EditIssueComponent implements OnInit {
IssuesList: any = [];
updateIssueForm: FormGroup;ngOnInit() {
this.updateForm()
}constructor(
private actRoute: ActivatedRoute,
public bugService: BugService,
public fb: FormBuilder,
private ngZone: NgZone,
private router: Router
) {
var id = this.actRoute.snapshot.paramMap.get('id');
this.bugService.GetIssue(id).subscribe((data) => {
this.updateIssueForm = this.fb.group({
issue_name: [data.issue_name],
issue_message: [data.issue_message]
})
})
}updateForm(){
this.updateIssueForm = this.fb.group({
issue_name: [''],
issue_message: ['']
})
}submitForm(){
var id = this.actRoute.snapshot.paramMap.get('id');
this.bugService.UpdateBug(id, this.updateIssueForm.value).subscribe(res => {
this.ngZone.run(() => this.router.navigateByUrl('/issues-list'))
})
}}
Head over to the components > edit-issue.component.html
file and paste the following code.
<div class="container wrapper wrapper2">Conclusion
<div class="row"><!-- Form --> <div class="col-md-12"> <h3>Add Issue</h3> <form [formGroup]="updateIssueForm" (ngSubmit)="submitForm()" novalidate> <div class="form-group"> <label>Issue</label> <input type="text" formControlName="issue_name" class="form-control" maxlength="20"> </div> <div class="form-group"> <label>Issue Details</label> <textarea class="form-control" formControlName="issue_message" rows="3" maxlength="50"></textarea> </div> <button type="submit" class="btn btn-primary">Update</button> </form> </div> </div>
</div>
Finally, we’ve completed the Angular 8 HttpClient & Http Tutorial. In this tutorial, we’ve learned how to make HTTP POST, GET, DELETE & PUT request to manage the data on the server along with some basic error handling. If you like this tutorial please share it with others. You can found GitHub repo here.
This post was originally published here
A simple example of how to implement server-side pagination in Angular 8 with a Node.js backend API.
This is a simple example of how to implement server-side pagination in Angular 8 with a Node.js backend API.
The example contains a hard coded array of 150 objects split into 30 pages (5 items per page) to demonstrate how the pagination logic works. Styling of the example is done with Bootstap 4.
The tutorial code is available on GitHub at https://github.com/cornflourblue/angular-8-node-server-side-pagination.
Here it is in action (may take a few seconds for the container to startup):
Running the Angular + Node Pagination Example Locallynpm install
command in the /server
folder.npm start
in the /server
folder, this will start the API on the URL http://localhost:4000.npm install
command in the /client
folder.npm start
in the /client
folder, this will build the app with webpack and automatically launch it in a browser on the URL http://localhost:8080.Below is the code for the paged items route (/api/items
) in the node server file (/server/server.js
) in the example, it creates a hardcoded list of 150 items to be paged, in a real application you would replace this with real data (e.g. from a database). The route accepts an optional page
parameter in the url query string, if the parameter isn't set it defaults to the first page.
The paginate()
function is from the jw-paginate
package and accepts the following parameters:
totalItems
(required) - the total number of items to be pagedcurrentPage
(optional) - the current active page, defaults to the first pagepageSize
(optional) - the number of items per page, defaults to 10maxPages
(optional) - the maximum number of page navigation links to display, defaults to 10The output of the paginate function is a pager object containing all the information needed to get the current pageOfItems
out of the items
array, and to display the pagination controls in the Angular frontend, including:
startIndex
- the index of the first item of the current page (e.g. 0
)endIndex
- the index of the last item of the current page (e.g. 9
)pages
- the array of page numbers to display (e.g. [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
)currentPage
- the current active page (e.g. 1
)totalPages
- the total number of pages (e.g. 30
)I've set the pageSize
to 5
in the CodeSandbox example above so the pagination links aren't hidden below the terminal console when the container starts up. In the code on GitHub I didn't set the page size so the default 10 items are displayed per page in that version.
The current pageOfItems
is extracted from the items
array using the startIndex
and endIndex
from the pager
object. The route then returns the pager object and current page of items in a JSON response.
// paged items route
app.get('/api/items', (req, res, next) => {
// example array of 150 items to be paged
const items = [...Array(150).keys()].map(i => ({ id: (i + 1), name: 'Item ' + (i + 1) }));
// get page from query params or default to first page
const page = parseInt(req.query.page) || 1;
// get pager object for specified page
const pageSize = 5;
const pager = paginate(items.length, page, pageSize);
// get page of items from items array
const pageOfItems = items.slice(pager.startIndex, pager.endIndex + 1);
// return pager object and current page of items
return res.json({ pager, pageOfItems });
});
Client-Side (Angular 8) Pagination Components
Since the pagination logic is handled on the server, the only thing the Angular client needs to do is fetch the pager information and current page of items from the backend, and display them to the user.
Below is the Angular home component (/client/src/app/home/home.component.ts
) from the example. The loadPage()
method fetches the pager
object and pageOfItems
for the specified page
from the backend API with an HTTP request, and the ngOnInit()
gets the page parameter in the route query params or defaults to the first page if the query param is empty.
By subscribing to the route.queryParams
observable, the home component is notified whenever the page changes so it can load the new page.
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ActivatedRoute } from '@angular/router';
@Component({ templateUrl: 'home.component.html' })
export class HomeComponent implements OnInit {
pager = {};
pageOfItems = [];
constructor(
private http: HttpClient,
private route: ActivatedRoute
) { }
ngOnInit() {
// load page based on 'page' query param or default to 1
this.route.queryParams.subscribe(x => this.loadPage(x.page || 1));
}
private loadPage(page) {
// get page of items from api
this.http.get(`/api/items?page=${page}`).subscribe(x => {
this.pager = x.pager;
this.pageOfItems = x.pageOfItems;
});
}
}
The home component template (/client/src/app/home/home.component.html
) renders the current page of items as a list of divs with the *ngFor
directive, and renders the pagination controls using the data from the pager
object. Each pagination link sets the page
query parameter in the url with the routerLink
directive and [queryParams]
property.
The CSS classes used are all part of Bootstrap 4.3, for more info see https://getbootstrap.com/docs/4.3/getting-started/introduction/.
### Angular 8 + Node - Server Side Pagination Example
{{item.name}}
First
Previous
{{page}}
Next
Last
I hope this tutorial will surely help and you if you liked this tutorial, please consider sharing it with others.
Thanks For Visiting, Keep Visiting.
Throughout my career, a multitude of people have asked me <em>what does it take to become a successful developer?</em>
Throughout my career, a multitude of people have asked me what does it take to become a successful developer?
It’s a common question newbies and those looking to switch careers often ask — mostly because they see the potential paycheck. There is also a Hollywood level of coolness attached to working with computers nowadays. Being a programmer or developer is akin to being a doctor or lawyer. There is job security.
But a lot of people who try to enter the profession don’t make it. So what is it that separates those who make it and those who don’t?