Opening A File Picker Programmatically Using Javascript In Angular

Introduction

In this article, we will see how to open a file picker using a javascript method in an Angular application. At times, our requirement will be different and we can't use input type="file" to open a file picker. We need to open a file picker programmatically using javascript. For this, we have a function called openFilePicker() which will open a file picker and return the selected file using promise. Suppose we have a component where we have to open a file-picker. 

Example Of Opening File Picker & Converting Image to Data URL

Suppose we have a component called image-upload. We will go to image-upload.component.html and write below code:

<div class="imageContainer">
      <img src="{{ imageURL }}" class="image" />
           <div style="  position: absolute;top: 0;bottom: 0;left: 0;right: 0;height: 100%;width: 100%;opacity: 0; transition: .5s 
               ease; background-color: rgba(0, 0, 0, 0.333);">
                    <span class="text-clickable text pointer" (click)="selectPhoto()">
                              ADD A PICTURE
                   </span>
            </div>
</div>

Now we will go to our image-upload.component.ts file and we will see a selectPhoto() method which is called when the user clicks on Add A PICTURE text in UI. 
In this method, we will call the openFilePicker() method which has three parameters: accept, multiple, and the returnEvent. The accept parameter indicates the supported file formats for the image and it is a string. The multiple parameter indicates whether a single image or multiple image file should be selected. The returnEvent indicates whether we have a return event from the method or not.
After we get the file from the openFilePicker() method, we have to convert this file into data URL to pass as src attribute in the <img> tag.

import { Component, OnInit, } from '@angular/core';
@Component({
  selector: 'app-image-upload',
  templateUrl: './image-upload.component.html',
  styleUrls: ['./image-upload.component.scss'],
 
})
export class SiteCreateComponent implements OnInit {
  imageURL: any;
 
  constructor(){}
   
    ngOnInit(){}
    
    selectPhoto() {
     let imageFile;
     this.openFilePicker(".jpg,.jpeg,.png", false, true)
      .then((file: File) => {
        imageFile = file;
      });
     if (imageFile) {
      let allowedExtensions =
        ["jpg", "jpeg", "png", "JPG", "JPEG", "PNG"];
      let name = imageFile.target.files[0].name;
      let extention = name.split('.').pop();
      if (allowedExtensions.filter((el) => el == extention).length == 0) {
       // Show Error To User
        }
     }
    this.imageURL = this.readasDataURL(imageFile);
}

  openFilePicker(accept?: string, multiple?: any, returnEvent: any): Promise {  // File Picker Function
   const input = document.createElement("INPUT");
    return new Promise((resolve, rej) => {
      input.setAttribute("type", "file");
      input.setAttribute("accept", accept || "image/*");
      if (multiple) {
        input.setAttribute("multiple", "multiple");
      }
      input.onchange = (event: any) => {
        if (event.target.value.length == 0) {
          reject("Input dialog canceled!");
        } else {
          resolve(event);
        }
      };
      input.style.display = 'none';
      document.body.appendChild(input);
      input.click();
    })
      .then(async (event: any) => {
        if (multiple) {
          return event.target.files;
        } else {
          return event.target.files[0];
        }
      })
      .catch(err => {
        console.error(err);
        document.body.removeChild(input);
      });
  }

 readAsDataURL(file: File): Promise {    // Converting file into dataURL here
    return new Promise((resolve, reject) => {
      if (file) {
        const reader = new FileReader();
        reader.onload = function (ev: any) {
          console.log('ev', ev);
          resolve(ev.target.result);
        };
        reader.readAsDataURL(file);
      } else {
        reject("File object not found!");
      }
    });
  }

Comments