Mrinalini Pal
Mrinalini Pal

Reputation: 509

Image preview before upload in angular 5

I have this code to show the image preview before uploading it. However I am working with Angular 5 so I have a .ts file instead of a .js one. How can I do the same in Angular 5? I also want to show the image in all browsers.

My HTML:

<input type='file' onchange="readURL(this);"/>
<img id="blah" src="http://placehold.it/180" alt="your image"/>

My CSS:

img {
    max-width:180px;
}

input[type=file] {
    padding: 10px;
    background: #2d2d2d;
}

My JavaScript:

function readURL(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();
        reader.onload = function (e) {
            document.getElementById('blah').src=e.target.result
        };
        reader.readAsDataURL(input.files[0]);
    }
}

Upvotes: 26

Views: 80990

Answers (9)

NIKHIL RATHORE
NIKHIL RATHORE

Reputation: 31

First we input the image by upload in choose file (imagedisplay.component.html) :

<input #Image type="file" (change)="handleFileInput($event.target.files)"/>
<img width="100%" *ngIf="imageUrl" [src]="imageUrl" class="image">
Then we use the function for reading and displaying further this is done so (imagedisplay.component.ts):

export class ImageDisplayComponent {
  name = 'Angular';
  fileToUpload: any;
  imageUrl: any;
  handleFileInput(file: FileList) {
    this.fileToUpload = file.item(0);

    //Show image preview
    let reader = new FileReader();
    reader.onload = (event: any) => {
      this.imageUrl = event.target.result;
    }
    reader.readAsDataURL(this.fileToUpload);
  }
}

Upvotes: 3

Faouzi
Faouzi

Reputation: 1019

For those who followed the accepted answer and had type 'string | ArrayBuffer' is not assignable to type 'string'; you need to add as string when affecting render result to your image src as the following

readURL(event: Event): void {
    ...
    reader.onload = e => this.imageSrc = reader.result as string;
    ...
}

}

Upvotes: 0

Slimane Deb
Slimane Deb

Reputation: 323

What about using @HostListner, since Angular doesn’t come with a built-in value accessor for file input.

  @HostListener('change', ['$event.target.files'])
  emitFiles( event: FileList ) {
    const file = event && event.item(0);
    this.onChange(file);
    const reader = new FileReader();
    reader.readAsDataURL(file); // toBase64
    reader.onload = () => {
      this.imageURL = reader.result as string; // base64 Image src
    };

Then in the HTML, you may use something like:

  <picture >
    <source media='(min-width:0px)' [srcset]="imageURL">
    <img src=""  [alt]="Your photo">
  </picture>

Upvotes: 3

abubakkar tahir
abubakkar tahir

Reputation: 847

to preview the chosen image before uploading this code will help you it,s easy. it,s preview only image if anything else then it,s will give you error this code is for component.ts

  public imagePath;
 imgURL: any;
 public message: string;
 preview(files) {
 if (files.length === 0)
  return;
 var mimeType = files[0].type;
 if (mimeType.match(/image\/*/) == null) {
  this.message = "Only images are supported.";
  return;
 }
 var reader = new FileReader();
 this.imagePath = files;
 reader.readAsDataURL(files[0]); 
 reader.onload = (_event) => { 
 this.imgURL = reader.result; 
}
}

and these lines of code in component view

 <span style="color:red;" *ngIf="message">{{message}}</span>
 <input #file type="file" accept='image/*' (change)="preview(file.files)" />
 <img [src]="imgURL" height="200" *ngIf="imgURL">

Upvotes: 2

Guruprasad J Rao
Guruprasad J Rao

Reputation: 29683

You might just need to change your javascript function to typescript as below.

readURL(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = (e:any) => {
             (<HTMLImageElement>document.getElementById('blah')).src=e.target.result 
             //assuming element with id blah will always be an ImageElement
        };

        reader.readAsDataURL(input.files[0]);
    }
}

That should be it.

Update

You can also define a property and bind it to image src and change its value accordingly as below:

In your .ts file before constructor, define a property as url and set its default value to http://placehold.it/180.

url: string = 'http://placehold.it/180';

You can update this property within reader.onload as below:

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]);
  }
}

Your html will now look like below:

<input type='file' (change)="readURL(this);" />
<img id="blah" [src]="url" alt="your image" />

Upvotes: 2

Joseph Vargas
Joseph Vargas

Reputation: 792

I know I'm late but just ran into this problem for both image and audio. The above solutions worked just fine for images but not so well for audio. I eventually got it all working by using a URL object instead of FileReader object that everyone is using. something like the following

component.ts file ~

imgSrc = 'assets/path/to/default/image.jpeg'

imgFileSelected(event: any) {
  if (event.target.files && event.target.files[0]) {
    this.imgSrc = URL.createObjectURL(event.target.files[0]);
  }
}

My component.html looks like~

<img [src]="imgSrc | sanitizeUrl"> <!-- using a Custom Pipe -->

Finally I created a custom pipe to rid the console of warnings. my pipe is as follows~

@Pipe({
  name: 'sanitizerUrl'
})
export class SanitizerUrlPipe implements PipeTransform {

  constructor (
    private sanitize: DomSanitizer
  ) {}

  transform(value: string): SafeUrl {
    return this.sanitize.bypassSecurityTrustUrl(value);
  }
}

To see how I used this for the audio tag you can check out this link. It's only 2 extra lines of self-explanatory code.

Upvotes: 15

Gopala Raja Naika
Gopala Raja Naika

Reputation: 2669

Kindly change like --> this.url = event.target.result;

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]);
    }
}

Upvotes: 2

fromage9747
fromage9747

Reputation: 344

I am using the below code to implement the image preview:

onFileChange(event: any) {
this.userFile = event.target.files[0];
this.imageSelected = this.userFile.name;
if (event.target.files && event.target.files[0]) {
  const reader = new FileReader();
  reader.onload = (e: any) => {
    this.imageSrc = e.target.result;
  };
  reader.readAsDataURL(event.target.files[0]);
}}

Which works just fine and displays the image preview. The problem I originally faced was that I receeived the below error in the chrome developer tools each time an image preview is generated:

null 404 GET Error

Everything worked fine though, there are no other errors.

If I clicked on the null:1 I was directed to the below:

null:1

After some fiddling and troubleshooting, I was able to find the solution which I have included in the edit below.

EDIT: Figured it out. I didn't have the || 'http://placehold.it/180'" included in the [src]=" on my component.html. Guess its a timing issue. Sorted now. no more error.

Upvotes: 6

Coffee-Tea
Coffee-Tea

Reputation: 1188

.html

Update event attr and handler param for input. And you should use data binding for src attribute. Following will apply src if it's not null or undefined or hardcoded url ('http://placehold.it/180')

<input type='file' (change)="readURL($event);" />
<img id="blah" [src]="imageSrc || 'http://placehold.it/180'" alt="your image" />

.ts

In component ts file (class) you should have property imageSrc which be used in view (html) and your function should be a method of that class

...
imageSrc: string;
...
constructor(...) {...}
...
readURL(event: Event): void {
    if (event.target.files && event.target.files[0]) {
        const file = event.target.files[0];

        const reader = new FileReader();
        reader.onload = e => this.imageSrc = reader.result;

        reader.readAsDataURL(file);
    }
}

Upvotes: 76

Related Questions