Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular - Clear File Input

I have a component that allows a user to fill out some fields as well as choose a profile picture. After submitting the form, I am trying to clear it so they could add another entry.

Component HTML:

<input type="file" #userPhoto name="userPhoto" id="userPhoto" (change)="onFileChange($event)" />

Component TS:

@ViewChild('userPhoto') userPhoto: any;

...

private prepareSave(value): any {
 const Image = this.userPhoto.nativeElement;
 if (Image.files && Image.files[0]) {
   this.userPhoto = Image.files[0];
 }
 const ImageFile: File = this.userPhoto;
 const formData: FormData = new FormData();
 formData.append('ParentUserID', value.parentUserID);
 formData.append('FirstName', value.firstName);
 formData.append('LastName', value.lastName);
 formData.append('Age', value.age);
 formData.append('Photo', ImageFile, ImageFile.name);
 return formData;
}

...

<Submit Form>
clearSelectedPhoto() {
  this.userPhoto.nativeElement.value = null;
}

Now, I think the issue is that my viewChild is using any instead of ElementRef. However, when I change this, typescript complains about my line in the prepareSave method:

const ImageFile: File = this.userPhoto;

[ts] Type 'ElementRef' is not assignable to type 'File'. Property 'lastModified' is missing in type 'ElementRef'.

How can I use ElementRef for my viewChild as well as assigning the photo to File later on?

I tried to cast it in my reset method but doesn't look like thats working either.

   clearSelectedPhoto() {
     (<ElementRef>this.userPhoto).nativeElement.value = null;
    }

Throws: ERROR Error: Uncaught (in promise): TypeError: Cannot set property 'value' of undefined

like image 788
SBB Avatar asked Oct 17 '25 10:10

SBB


1 Answers

You have to get file from change event.

Component HTML:

<input #userPhoto type="file" (change)="fileChange($event)"/>

Component TS:

@ViewChild('userPhoto') userPhoto: ElementRef;
private _file: File;

private prepareSave(value): FormData {
    const formData: FormData = new FormData();
    formData.append('ParentUserID', value.parentUserID);
    formData.append('FirstName', value.firstName);
    formData.append('LastName', value.lastName);
    formData.append('Age', value.age);
    formData.append('Photo', this.file, this.file.name);
    return formData;
}


fileChange(event) {
    this.file = event.srcElement.files[0];
}
clearSelectedPhoto() {
    this.userPhoto.nativeElement.value = null;
}

When you use TS be shure to declare types everywhere you can, it avoids alot of misstakes. Don't return any from functions. Even if your function returns several types point on it in your function declaration ex: getFile(): File | string.

Don't use the same variable like this:

@ViewChild('userPhoto') userPhoto: any;
...
    if (Image.files && Image.files[0]) {
       this.userPhoto = Image.files[0];
    }

In your code you overwrote pointer to input element with file, and then when you tried to clear it's value this.userPhoto.nativeElement.value = null; you actualy wrote to Image.files[0].value = null;.

like image 134
Dmitriy Snitko Avatar answered Oct 19 '25 23:10

Dmitriy Snitko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!