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

12 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
  5. extraouss said:

    I did the same think but the event.type doesn’t send me HttpEventType.UploadProgress, it sends only 4 ( which is Response I don’t know why :/ )

    September 6, 2019
    Reply
    • w3path said:

      Can you share your code here? and second did you try uploading big file? If no please try once

      September 7, 2019
      Reply
      • extraouss said:

        yes I tried I big file but it’s the same :/, thank your for answering; I share with you my code ( I’m blocked for 3 days )
        const formData = new FormData();
        formData.append(‘file’, file, file.name);
        this.http
        .request(
        new HttpRequest(‘POST’, `http://localhost:4200/api/documents/102/file`, formData, {
        reportProgress: true,
        headers: new HttpHeaders({
        Authorization:
        ‘Bearer eyJrKJhgFNBUhTMDBDa…..’
        })
        })
        )
        .subscribe((events) => {
        console.log(events.type);
        });

        September 9, 2019
        Reply
  6. sandeep said:

    how to prevent from fake path issue while uploading file in angular 8?

    October 1, 2019
    Reply
  7. Jay Allard said:

    Thank you for this guide. It’s a great start.
    While working with it, I found that it’s not tolerant of change. IE: Choose an image, then open the file dialog again again and click cancel; no file chosen but the preview remains. The same if you choose an image, then choose a non-image.

    October 2, 2019
    Reply
  8. Garrick Wheeler said:

    Thanks, but I found that on mobile safari, the page would reload after selecting an image, shortly after the preview appears, the page would refresh and content would all be reset.

    October 9, 2019
    Reply
  9. mehdi said:

    thank you vary much

    November 1, 2019
    Reply

Leave a Reply

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