11

I am very new to typescript and web development in general so I am sorry if my code is terrible. Anyways, I am having an issue displaying a "preview image" for a profile picture upload. I am using ng2-file-upload to upload my image to the server and that part is working correctly. Before I click the upload button I want to display the selected image on the page right after it has been selected. Currently I am trying to display the image by retrieving the src property from the HTMLImageElement but the src property appears to be empty.

import { Component, OnInit } from '@angular/core';
import {  FileUploader } from 'ng2-file-upload/ng2-file-upload';

const URL = 'http://localhost:4200/api/upload';

@Component({
  selector: 'app-view-profile',
  templateUrl: './view-profile.component.html',
  styleUrls: ['./view-profile.component.css']
})
export class ViewProfileComponent implements OnInit {

  constructor() { }
  public uploader: FileUploader = new FileUploader({url: URL, itemAlias: 'newProfilePicture'});
  title: string;
  previewImage: any;
  tempImage: any;
  source: string;

  imagePreview(input) 
  {
      document.getElementById("previewImage").style.display="block";
      
        console.log("Image is selected")
        this.previewImage = document.getElementById("previewImage");
        console.log(this.previewImage);
        
        this.source = (<HTMLImageElement>document.getElementById('previewImage')).src
        console.log("Image Source: " + this.source + " Should be inbetween here");
        
      
      //var reader = new FileReader();
        
        //console.log(this.previewImage);
      
  }

  ngOnInit() {
   this.title = 'View or Update Your Profile';
   this.uploader.onAfterAddingFile = (file)=> {file.withCredentials = false;};
   this.uploader.onCompleteItem = (item:any, response:any, status:any, headers:any) => {
        console.log("ImageUpload:uploaded:", item, status, response);
    //this.imagePreview();


    };
  }


}

And here is my HTML

<div class="container">
    <h1>{{title}}</h1>

    <div>

        <input type="file" id="previewImage" (change)="imagePreview(this);" name="newProfilePicture" ng2FileSelect [uploader] ="uploader" />
        <button type="button" class="btn btn-success btn-s" (click)="uploader.uploadAll()" [disabled]="!uploader.getNotUploadedItems().length">
          Upload Your File
        </button>
    </div>
</div>
Kenny Ho
  • 111
  • 1
  • 1
  • 3

2 Answers2

29

You achive this by this simple function :

Template :

<img [src]="url" height="200"> <br/>
<input type='file' (change)="onSelectFile($event)">

Component :

onSelectFile(event) { // called each time file input changes
    if (event.target.files && event.target.files[0]) {
      var reader = new FileReader();

      reader.readAsDataURL(event.target.files[0]); // read file as data url

      reader.onload = (event) => { // called once readAsDataURL is completed
        this.url = event.target.result;
      }
    }
}

Here is the working example of it, please check this out:

WORKING DEMO

Vivek Doshi
  • 46,471
  • 9
  • 84
  • 100
  • 1
    @Kenny Ho, will you please accpet and upvote the answer? – Vivek Doshi Nov 07 '17 at 05:59
  • 2
    @VivekDoshi I got `error TS2339: Property 'result' does not exist on ty pe 'EventTarget'.` which is this line inside of onSelectFile(event) `this.url = event.target.result;` If I change it to anything, ng cli will auto-recompile successfully. Repeat will create get the error back. Any thought? – Jeb50 Jul 28 '18 at 17:51
  • Jeb50 Add `` cast to `event.target.files` and `event.target.files[0]` – Mr. Wizard Aug 09 '18 at 11:03
  • 1
    I have used this code but for me it is working but with two problems at reader.onload = (event) [tslint] Shadowed name: 'event' (no-shadowed-variable and to the this.person.photo = event.target.result // Property 'result' does not exist on type 'EventTarget' – Abedin.Zhuniqi Aug 29 '18 at 07:47
  • Regarding the TS error, instead of using event.target.result, you can just use reader.result – Kaixin Apr 26 '20 at 09:14
7

Template :

<input type='file' (change)="readUrl($event)">
<img [src]="url">

Component :

 readUrl(event:any) {
      if (event.target.files && event.target.files[0]) {
          var reader = new FileReader();

          reader.onload = (event:any) => {
              this.url = event.target.result;
          }

          reader.readAsDataURL(event.target.files[0]);
      }
 }

T tried it, and it works without any error.

juzraai
  • 4,835
  • 8
  • 26
  • 41
Iron shield
  • 291
  • 4
  • 9
  • I have used this code but it is showing me one error reader.onload = (event:any) // event Shadowed name: 'event' (no-shadowed-variable) – Abedin.Zhuniqi Aug 30 '18 at 08:40