4

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

2 Answers 2

9

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

Sign up to request clarification or add additional context in comments.

Comments

-1

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 = "";
  
  }


}

1 Comment

Doesnt work. The input file is still remembering the previous file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.