Today we are going to learn how to upload a file and create a progress bar in an Angular 8|9 app using HttpClient, HttpEvent, and HttpEventType APIs. A progress bar is a graphical UI representation to visualize the progress of programmatic operation such as uploading, downloading, transfer, and installation of a data.
We will be setting up a basic Angular app with Express API and make the Http POST request to send the user name and image to the server. The Primary purpose of this tutorial is to learn how to listen to the progress of the HTTP requests, especially when the data is being uploaded to the webserver.
Install an Angular app from scratch to show you the file upload and progress bar demo:
ng new fileupload-progressbar-angular
# ? Would you like to add Angular routing? Yes
# ? Which stylesheet format would you like to use? CSS
Get inside the project folder:
cd fileupload-progressbar-angular
Install and set up the Bootstrap 4 UI framework.
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { HttpErrorResponse, HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class FileUploadService {
constructor(private http: HttpClient) { }
addUser(name: string, profileImage: File): Observable<any> {
var formData: any = new FormData();
formData.append("name", name);
formData.append("avatar", profileImage);
return this.http.post('http://localhost:4000/api/create-user', formData, {
reportProgress: true,
observe: 'events'
}).pipe(
catchError(this.errorMgmt)
)
}
errorMgmt(error: HttpErrorResponse) {
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);
}
}
Inject the bootstrap style-sheet in the styles array in package.json
file.
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
]
Run the command to start your Angular File upload with progress bar app.
ng serve --open
Let’s set up a node server, we need to take a git clone. Run the given below command while staying in the root of our Angular project.
git clone https://github.com/SinghDigamber/nodejs-file-upload-server.git backend
# Cloning into 'backend'...
# remote: Enumerating objects: 4017, done.
# remote: Counting objects: 100% (4017/4017), done.
# remote: Compressing objects: 100% (2958/2958), done.
# remote: Total 4017 (delta 858), reused 4013 (delta 857), pack-reused 0
# Receiving objects: 100% (4017/4017), 3.98 MiB | 1.14 MiB/s, done.
# Resolving deltas: 100% (858/858), done.
# Checking out files: 100% (3947/3947), done.
Next, get into the backend folder and install the required dependency.
$ cd backend
$ npm install
Once the required packages installed then run the following command to start the mongoDB database.
mongod
Then, start the nodemon server by using the following command.
nodemon
Once your server is up and running, then you can check your Node server app on the following Urls: http://localhost:4000
/api
: for showing users list/api/create-user
: for creating userBefore creating file upload service, we need to import the HttpClientModule service in app.module.ts
file.
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [...],
imports: [
HttpClientModule
],
bootstrap: [...]
})
export class AppModule { }
In this step, we will create file upload service with HttpClient run the following command to create the service.
ng generate service file-upload
Next, open the src/app/file-upload.service.ts
file and add the following code
inside of it.
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { HttpErrorResponse, HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class FileUploadService {
constructor(private http: HttpClient) { }
addUser(name: string, profileImage: File): Observable<any> {
var formData: any = new FormData();
formData.append("name", name);
formData.append("avatar", profileImage);
return this.http.post('http://localhost:4000/api/create-user', formData, {
reportProgress: true,
observe: 'events'
}).pipe(
catchError(this.errorMgmt)
)
}
errorMgmt(error: HttpErrorResponse) {
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);
}
}
Create a form that will allow uploading data to the server. Import the ReactiveFormsModule API in the app.module.ts
file.
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [...],
imports: [
ReactiveFormsModule
],
bootstrap: [...]
})
export class AppModule { }
Build a file upload form with Bootstrap 4 form components and Reactive Forms APIs.
Go to app/app.component.html
file and add the following code:
<div class="container">
<form [formGroup]="form" (ngSubmit)="submitUser()">
<!-- Progress Bar -->
<div class="progress form-group" *ngIf="progress > 0">
<div class="progress-bar progress-bar-striped bg-success" role="progressbar" [style.width.%]="progress">
</div>
</div>
<div class="form-group">
<input type="file" (change)="uploadFile($event)">
</div>
<div class="form-group input-group-lg">
<input class="form-control" placeholder="Name" formControlName="name">
</div>
<div class="form-group">
<button class="btn btn-danger btn-block btn-lg">Create</button>
</div>
</form>
</div>
Next, go to app.component.ts
file and add the following code inside of it.
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from "@angular/forms";
import { FileUploadService } from "./file-upload.service";
import { HttpEvent, HttpEventType } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
form: FormGroup;
progress: number = 0;
constructor(
public fb: FormBuilder,
public fileUploadService: FileUploadService
) {
this.form = this.fb.group({
name: [''],
avatar: [null]
})
}
ngOnInit() { }
uploadFile(event) {
const file = (event.target as HTMLInputElement).files[0];
this.form.patchValue({
avatar: file
});
this.form.get('avatar').updateValueAndValidity()
}
submitUser() {
this.fileUploadService.addUser(
this.form.value.name,
this.form.value.avatar
).subscribe((event: HttpEvent<any>) => {
switch (event.type) {
case HttpEventType.Sent:
console.log('Request has been made!');
break;
case HttpEventType.ResponseHeader:
console.log('Response header has been received!');
break;
case HttpEventType.UploadProgress:
this.progress = Math.round(event.loaded / event.total * 100);
console.log(`Uploaded! ${this.progress}%`);
break;
case HttpEventType.Response:
console.log('User successfully created!', event.body);
setTimeout(() => {
this.progress = 0;
}, 1500);
}
})
}
}
i hope you like this article.
Hi, My name is Harsukh Makwana. i have been work with many programming language like php, python, javascript, node, react, anguler, etc.. since last 5 year. if you have any issue or want me hire then contact me on harsukh21@gmail.com
How to Remove a Property from a JavaScript Object
Use the delete Operator You...How to disabled Submit Button after Clicked using jQuery
Often times, users like to press a few t...Data Binding in Angular9
In this Angular tutorial, we are going t...Hash Password with Bcrytp in NodeJs
In this tutorial, we will learn to ...Django - How to Uploading File with Example
It is generally useful for a web app to...