SBB
SBB

Reputation: 8980

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

Upvotes: 4

Views: 25594

Answers (2)

shubham kumar
shubham kumar

Reputation: 331

you need to get the element using @ViewChild then make the element empty to remove the file


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


 #component.ts{
  @ViewChild('userPhoto')
  myInputVariable: ElementRef;

  onFileChange(event){

   // when you done with process - clear the file
   this.myInputVariable.nativeElement.value = "";
  
  }


}

Upvotes: -1

Dmitriy Snitko
Dmitriy Snitko

Reputation: 960

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;.

Upvotes: 9

Related Questions