Reputation: 509
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
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">
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
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
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
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
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
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
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
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:
Everything worked fine though, there are no other errors.
If I clicked on the null:1 I was directed to the below:
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
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