New Angular 8 File Upload or Image Upload with Preview and Progress Report

Image upload or file upload is a common requirement of the application. In this Angular 8 tutorial we will learn File upload, file uploading progress and Image Preview. You can follow this tutorial for angular 7 also

Before start learning file upload, We need a Angular 8 Project. If you don’t know how to create a new project. Follow Angular 8 installation guide tutorial.

So let’s get started

Create template

First we need to create template. In this template we will create file input element that allows to us to choose the file and a button to submit the form. To create it open the app.component.html file and put the below html on it. Instead of app.component.html you can put on another component too!

<div class="container">
    <div class="row">
        <div class="col-md-6 offset-md-3">
            <h3>Choose File</h3>            
            <div class="form-group">
                <input type="file" name="image" (change)="fileProgress($event)" />
            </div>
            <div *ngIf="fileUploadProgress">
                Upload progress: {{ fileUploadProgress }}
            </div>
            <div class="image-preview mb-3" *ngIf="previewUrl">
                <img [src]="previewUrl" height="300" />                 
            </div>

            <div class="mb-3" *ngIf="uploadedFilePath">
                {{uploadedFilePath}}
            </div>
            
            <div class="form-group">
                <button class="btn btn-primary"  (click)="onSubmit()">Submit</button>
            </div>
        </div>
    </div>
</div>

Configure the HttpClientModule

We will use the Angular 8 HttpClient to upload the file on the server.

So before writing file upload code, first, Open src/app/app.module.ts then add this import.

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

Add HttpClientModule to imports array under @NgModule

imports: [
	HttpClientModule
]

Now open the app.component.ts file and put the below code on it

fileData: File = null;
previewUrl:any = null;
fileUploadProgress: string = null;
uploadedFilePath: string = null;
constructor(private http: HttpClient) { }

fileProgress(fileInput: any) {
      this.fileData = <File>fileInput.target.files[0];
      this.preview();
}

preview() {
    // Show preview 
    var mimeType = this.fileData.type;
    if (mimeType.match(/image\/*/) == null) {
      return;
    }

    var reader = new FileReader();      
    reader.readAsDataURL(this.fileData); 
    reader.onload = (_event) => { 
      this.previewUrl = reader.result; 
    }
}

onSubmit() {
    const formData = new FormData();
      formData.append('file', this.fileData);
      this.http.post('url/to/your/api', formData)
        .subscribe(res => {
          console.log(res);
          this.uploadedFilePath = res.data.filePath;
          alert('SUCCESS !!');
        })
}

Here you can see the three methods onSubmit , preview and fileProgress. The fileProgress method will called when the user choose file. It will get the file object of selected file and store in the fileData.

The preview method will get the data from fileData variable and read the file and show the image in our webpage.

The onSubmit function will called when the form submit. Here we have created a formData object. We will store the file object to the formData and then upload it to the server via Angular 8 HttpClient

After the changes our app.component.ts file will looks like this

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

@Component({
  selector: 'app-image-upload-with-preview',
  templateUrl: './image-upload-with-preview.component.html',
  styleUrls: ['./image-upload-with-preview.component.css']
})

export class ImageUploadWithPreviewComponent implements OnInit {

  fileData: File = null;
  previewUrl:any = null;
  fileUploadProgress: string = null;
  uploadedFilePath: string = null;
  constructor(private http: HttpClient) { }
  
  ngOnInit() {
  }
  
  fileProgress(fileInput: any) {
      this.fileData = <File>fileInput.target.files[0];
      this.preview();
  }

  preview() {
    // Show preview 
    var mimeType = this.fileData.type;
    if (mimeType.match(/image\/*/) == null) {
      return;
    }

    var reader = new FileReader();      
    reader.readAsDataURL(this.fileData); 
    reader.onload = (_event) => { 
      this.previewUrl = reader.result; 
    }
  }
  
  onSubmit() {
      const formData = new FormData();
      formData.append('file', this.fileData);
      this.http.post('url/to/your/api', formData)
        .subscribe(res => {
          console.log(res);
          this.uploadedFilePath = res.data.filePath;
          alert('SUCCESS !!');
        }) 
  }
}

Now you can upload the file, But in some case you need more control

Progress Event

If you are dealing with the big file or You may want to show progress to user, Angular 8 httpClient gives you the progress status.

First of all open the app.component.ts file and put the below import

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

Then you just need to add reportProgress to true and set the observe to events in the config like we have below. You will get all the events on subscribe

onSubmit() {
    const formData = new FormData();
    formData.append('files', this.fileData);
    
    this.fileUploadProgress = '0%';

    this.http.post('https://us-central1-tutorial-e6ea7.cloudfunctions.net/fileUpload', formData, {
      reportProgress: true,
      observe: 'events'   
    })
    .subscribe(events => {
      if(events.type === HttpEventType.UploadProgress) {
        this.fileUploadProgress = Math.round(events.loaded / events.total * 100) + '%';
        console.log(this.fileUploadProgress);
      } else if(events.type === HttpEventType.Response) {
        this.fileUploadProgress = '';
        console.log(events.body);          
        alert('SUCCESS !!');
      }
        
    }) 
}

Here is the working demo

5 Comments

  1. daivd said:

    Great example! thank you

    August 6, 2019
    Reply
  2. Pradyot said:

    Nice and simple Great !!

    August 10, 2019
    Reply
  3. vidya said:

    this.http.post(‘http://165.22.219.195:4000/api/vendor-registration’,{vendor_name:this.Vname,company_email:this.Vcompany,phone:this.Vphone,formData,{
    reportProgress: true,
    observe: ‘events’
    })

    August 23, 2019
    Reply
  4. vidya said:

    this.http.post(‘http://165.22.219.195:4000/api/vendor-registration’,formData, {
    reportProgress: true,
    observe: ‘events’
    },) in this where i assign
    {vendor_name:this.Vname,company_email:this.Vcompany,phone:this.Vphone}

    August 23, 2019
    Reply
    • w3path said:

      This seems like you want to send some additional information to the server.
      If yes then you can add all your data in formData variable like below

      const formData = new FormData();
      formData.append(‘file’, this.fileData);
      formData.append(‘vendor_name’, this.Vname);
      formData.append(‘company_email’, this.Vcompany);
      formData.append(‘phone’, this.Vphone);
      this.http.post(‘url/to/your/api’, formData)
      .subscribe(res => {
      console.log(res);
      this.uploadedFilePath = res.data.filePath;
      alert(‘SUCCESS !!’);
      })

      August 24, 2019
      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *