I have a simple upload form and would like to bind the displayed filename to the value of the file input field <input type="file">, but for some reason it always shows some virtual filepath. How can the binding be improved to not have this behavior(only filename, like selected.files[0].name)?
Ideally the selected filename would be shown in the label for #selected right after the OS filechooser finishes. Another approach of mine is included in the comments (*ngIf), but it doesn't work either.
<form>
<div class="justify-content-center">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Select image</span>
</div>
<div class="custom-file">
<input type="file" accept="image/*" class="custom-file-input" id="selected" #selected (click)="message=''" >
<label class="custom-file-label" for="selected">{{ selected.value }}</label>
<!--
<div *ngIf="selected.files[0].name; then showFilename else showDefaultMsg"></div>
<ng-template #showFilename>
<label class="custom-file-label" for="selected">{{ selected.files[0].name }}</label>
</ng-template>
<ng-template #showDefaultMsg>
<label class="custom-file-label" for="selected">Choose file....</label>
</ng-template>
-->
</div>
</div>
<button [disabled]="!selected.value" id="uploadBtn" class="btn btn-primary" (click)="onUpload(selected)">Upload</button>
<div class="text-center" *ngIf="message">
<div class="spinner-border" role="status">
<span class="sr-only">Loading....</span>
</div>
<div>{{ message }}</div>
</div>
</div>
</form>
Thanks
I don't believe you can reference the value like that and pick up changes. selected is an HTMLInputElement, not an Observable<HTMLInputElement> or any other thing that is going to emit the value on change.
In the below example, you'll see that the same setup with a text box shows what you would expect on page load, but doesn't actually pickup any changes to the input value.
StackBlitz here
You need to either use ngModel, FormControl, or just create an event for the change event.
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
fileName = null;
onFileChange(evt): void {
this.fileName = evt.target.files[0].name;
}
}
Template
<hello name="{{ name }}"></hello>
<input type="text" #myInput value="Init Text" />
<div>Input Text: {{myInput.value}}</div>
<input type="file" (change)="onFileChange($event)" />
<div>name: {{fileName}}</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With