11

I was able to successfully upload a file, but the problem now is it won't let me upload the same file twice. Here's my code:

 <input type="file" (change)="onFileChange($event)" name="fileUploaded" value="Choose a File" accept=".xlsx, .xlsm">

I found out that the onFileChange($event) won't fire since the listener I used is (change) and I'm not changing the file the I'm uploading. What can I do to sovle my problem? Thank you

EDIT: To give you context why would I want to do that, I want to upload an excel file then display its content to the page. But when I upload an excel file then edit its data inside using ms excel then save and upload it again, the new edits won't display on the page. The page still displays the old data.

Here's my code for the eventHandler:

data: AOA = [ [], [] ];
reader: FileReader = new FileReader();
onFileChange(evt: any) {
        /* wire up file reader */
        console.log("G");
        const target: DataTransfer = <DataTransfer>(evt.target);
        this.reader.onload = (e: any) => {
            /* read workbook */
            this.data = [ [], [] ];
            console.log(target.types);
            const bstr: string  = e.target.result;
            const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
            /* grab first sheet */
            const wsname: string = wb.SheetNames[0];
            const ws: XLSX.WorkSheet = wb.Sheets[wsname];
            /* save data */
            this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
        }
            this.reader.readAsBinaryString(target.files[0]);
    }
1
  • clear the input at the end of your 'onFileChange' function Commented Apr 23, 2018 at 8:44

8 Answers 8

23

You can reference and then clear your input:

template

<input #myFileInput type="file"/>

script

@ViewChild('myFileInput') myFileInput;

onFileChange(event) { 
  this.myFileInput.nativeElement.value = '';
}
Sign up to request clarification or add additional context in comments.

8 Comments

Hi. Do I have to make another component for it? or I'll just insert in on my current typescript file? Do I have to change that 'MyFileInput' or ill just copy and paste it directly? Sorry im really new to this.
Just insert it in your own files. You can name myFileInput to whatever you want.
Still won't work. I believe the reason is I'm trying to upload the same file but the onFileChange($event) won't fire since the listener is (change) and I'm uploading the same file though the contents are different.
That's why you clear the input so it doesn't know about the previous file being the same.
My apologies, it's: this.myFileInput.nativeElement.value = ''';
|
8

Its sort of gets cached . so just make sure u are cleaning it before uploading the file so what u can do is give the value as empty and then upload the file

<input type ="file" #fileUpload style="visibility: hidden;" (change)="uploadResume($event)"> 
<button (click)="fileUpload.value='';fileUpload.click();">Upload</button>

Comments

4

You can reference and then clear your input:

template

<input (click)="clearFile()" #myFileInput type="file"/>

script

@ViewChild('myFileInput') myFileInput;

clearFile(event) { 
  this.myFileInput.nativeElement.value = '';
}

Comments

2

just try (onclick)="this.value = null"

in your html page add onclick method to remove previous value so user can select same file again.

1 Comment

A bit more explanation might improve this answer.
0

You can try this way also. I was able to upload the same Image twice.

app.component.html

<p>App image</p>
<input matInput [disabled]="true" />
<input #imageInput accept="image/*" (change)="selectImageFile(imageInput)" type="file" id="file" (click)="imageInput.value='';">

app.component.ts

selectImageFile(imageInput: any) {
let file: File = imageInput.files[0];
const reader = new FileReader();
reader.addEventListener('load', (event: any) => {
  this.selectedFile = new ImageSnippet(event.target.result, file);
  this.applicationService.imageUpload(this.selectedFile.file).subscribe(
    (res) => {
      this.isImageSubmitted = true;
      this.selectedImagename = res.data;
    },
    (err) => {
      this.isImageSubmitted = false;
    }
  );
});
reader.readAsDataURL(file);

}

1 Comment

This is the most correct answer, if 1- we do not need some external button, and 2- there is only one input field with (click) event to clear the file and (change) event for upload (input event can also be used instead of change). This always ensures (click) event will clear file before (change) event. P.S. - Just to be clear, we do not need first <input matInput [disabled]="true" />. And Please edit and remove all the code in selectImageFIle() function, and it would be a perfect answer for upvote. :)
0

you can achieve it like below

<input type="file" #fileInput style="display: none"  accept=".csv"  (change)="OnFileSelected($event)" (click)="$event.target.value=null"/>

Comments

0

Most easiest way to achieve this is to set input (file type) value to null on click as

onclick="this.value = null"

Like your input should be

<input type="file" (change)="onFileChange($event)" name="fileUploaded" value="Choose a File" accept=".xlsx, .xlsm" onclick="this.value = null">

Answer is Already given here

Comments

0

Angular 18. Setting value to empty string on click event compiled and worked:

<input
    type="file"
    #fileInput
    accept="image/*"
    (change)="onFileChanged($event)"
    (click)="fileInput.value = ''"
/>

Comments

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.