How to upload file in Angular app and show the progress with example

Angular is a platform for building mobile and desktop web applications. It’s extremely popular with developers who use it not just for its features, but also for its simplicity.

In this tutorial we’ll show you how to upload a file in Angular and show progress bar with fake backend.

To follow along with this tutorial, you will need to have Node installed on your machine. You can follow this guide to install Node on your machine if you don’t already have it installed.

You’ll also need a local Express application that can transfer files to the browser via a POST request. For this, I’m using fake backend that simulates the backend.

The first step is creating our app and installing all dependencies required:

fake-http.ts

import {
  HttpEvent,
  HttpEventType,
  HttpHandler,
  HttpInterceptor,
  HttpRequest,
  HttpResponse,
  HTTP_INTERCEPTORS,
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { delay, Observable, of } from 'rxjs';
//https://jasonwatmore.com/post/2020/07/18/angular-10-user-registration-and-login-example-tutorial#account-service-ts
@Injectable({
  providedIn: 'root',
})
export class FakeHttpService implements HttpInterceptor {
  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const { url, method, body } = request;
    return handleRoute();
    function handleRoute() {
      switch (true) {
        case url.endsWith('api/Upload') && method === 'POST':
          return uploadFile();

        default:
          // pass through any requests not handled above
          return next.handle(request);
      }
    }

    function uploadFile() {
      const file = body.get('file');
      const totalSize = file.size;

      let uploadedSize = 0;
      const progress$ = new Observable<HttpEvent<any>>((subscriber) => {
        console.log('uploading file...');
        const interval = setInterval(() => {
          uploadedSize += 1000;
          subscriber.next({
            type: HttpEventType.UploadProgress,
            loaded: uploadedSize,
            total: totalSize,
          });
          if (uploadedSize >= totalSize) {
            clearInterval(interval);
            subscriber.complete();
          }
        }, 1500);
      });
      return progress$;
    }
  }
}


export const fakeBackendProvider = {
  // use fake backend in place of Http service for backend-less development
  provide: HTTP_INTERCEPTORS,
  useClass: FakeHttpService,
  multi: true,
};

The ‘HttpInterceptor’ API allows you to intercept incoming and outgoing requests before they are handled by the web framework. I’m using it here to simulate uploading a file, which will be returned as if it were successful without actually doing anything.

file-upload.component.html

<form #uploadForm="ngForm">
  <input type="file" (change)="upload($event)" placeholder="Upload file" />
</form>
<progress id="file" [value]="progress" max="100">{{ progress }}</progress>

The following html snippet is very simple and self explanatory . In the above html snippet I have added a file input type and HTML5 progress bar component. When the user select the file change event triggers and then send the information to the component.

file-upload.component.ts

//Upload file using angular and show progress bar

import { Component, OnInit } from '@angular/core';

import { HttpClient, HttpEventType } from '@angular/common/http';

@Component({
  selector: 'app-upload',
  templateUrl: './file-upload.component.html',
  styleUrls: ['./file-upload.component.scss'],
})
export class FileUploadComponent implements OnInit {
  public progress: number;
  public message: string;

  constructor(private http: HttpClient) {}
  ngOnInit() {}
  public upload(event) {
    let fileToUpload = event.target.files[0];
    const formData = new FormData();
    formData.append('file', fileToUpload, fileToUpload.name);
    this.http
      .post('https://localhost:4200/api/Upload', formData, {
        reportProgress: true,
        observe: 'events',
      })
      .subscribe((event) => {
        if (event.type === HttpEventType.UploadProgress) {
          this.progress = Math.round((100 * event.loaded) / event.total);
          console.log(this.progress);
        } else if (event.type === HttpEventType.Response) {
          this.message = 'Upload success.';

          fileToUpload = null;
        }
      });
  }
}

In the preceding code snippet, I’m sending an HTTP post request with HttpClient Include reportProgress: true and observe: events in your post request to receive progress events. By enabling these properties, we will get the event HttpEventType.UploadProgress and we will compute and display the percentage in the progress bar.

Do not forgot to add the http interceptor in app module


@NgModule({
  declarations: [AppComponent FileUploadComponent],
  imports: [
    BrowserModule,
   HttpClientModule,
    ReactiveFormsModule,
    FormsModule,
    CommonModule,
   
  ],
  providers: [fakeBackendProvider],
  bootstrap: [AppComponent],
})
export class AppModule {}

1 Comments

Please do not post any spam link in the comment box😊

  1. Nice article on this topic and very clean code

    ReplyDelete
Post a Comment
Previous Post Next Post