I have an Angular app that uses a p-fileUpload component that has its [multiple] attribute set to true such that it can upload multiple files at once.
So far this has worked rather well. In particular because I can use the (onSelect) function to pass in all of the files that have been selected to do some error checking.
Problem is I haven't been able to do the same thing and pass in all of the files when a file is removed.
In the ngOnInit() function in my ts file, I add an UntypedFormControl called 'files'
this.form = this._fb.group({
'files': new UntypedFormControl({value: null, disabled: !this.allowFileUpload}, [Validators.required])
});
In my html file, I implement a p-fileUpload component that sets the 'files' form control to the files selected by the user
<p-fileUpload #fileUpload styleClass="col-12" chooseStyleClass="col-3" chooseLabel="Choose File(s)..."
(onSelect)="form.get('files').setValue($event.currentFiles);form.markAsDirty(); onFilesSelectedToUpload($event.currentFiles)"
[multiple]="true">
This passes the files to the ts file to do whatever I want with them
onFilesSelectedToUpload(files: any[]) {
files.forEach(file => {
}
}
What I would like to do is do something similar when the user removes one of the files.
The implementation below doesn't work, though, as there is no $event.currentFiles to pass in when onRemove is triggered.
<p-fileUpload #fileUpload styleClass="col-12" chooseStyleClass="col-3" chooseLabel="Choose File(s)..."
(onSelect)="form.get('files').setValue($event.currentFiles);form.markAsDirty(); onFilesSelectedToUpload($event.currentFiles)"
(onRemove)="form.get('files').setValue($event.currentFiles); onRemoveFile($event.currentFiles)"
[multiple]="true">
Any suggestions?
Thanks much.
Would recommend you keep multiples lines of logic in a separate method instead of on the HTML so that it can be tested in the future.
We can get the files already present in the form, then use array filter
method to filter that particular file that was removed using event.file
, which is just a reference in memory, so we can use file !== event.file
to compare the file memory references and exclude the file that was removed. After removing, we again patch it back to the form.
onFilesSelectedToUpload(files: any[]) {
console.log(files);
files.forEach((file) => {});
}
onSelect(event: FileSelectEvent) {
this.form.get('files').setValue(event.currentFiles);
this.form.markAsDirty();
this.onFilesSelectedToUpload(event.currentFiles);
}
onRemove(event: FileRemoveEvent) {
const filesCtrl = this.form.get('files');
const files = filesCtrl.value;
filesCtrl.patchValue(files.filter((file: File) => file !== event.file));
this.onFilesSelectedToUpload(filesCtrl.value);
}
<div class="card flex justify-content-center">
<p-toast />
<p-fileUpload
name="demo[]"
url="https://www.primefaces.org/cdn/api/upload.php"
(onUpload)="onUpload($event)"
(onSelect)="onSelect($event)"
(onRemove)="onRemove($event)"
[multiple]="true"
accept="image/*"
maxFileSize="1000000"
>
<ng-template pTemplate="content">
<ul *ngIf="uploadedFiles.length">
<li *ngFor="let file of uploadedFiles">
{{ file.name }} - {{ file.size }} bytes
</li>
</ul>
</ng-template>
</p-fileUpload>
</div>
import { Component, inject } from '@angular/core';
import { ImportsModule } from './imports';
import { MessageService } from 'primeng/api';
import {
ReactiveFormsModule,
FormBuilder,
FormControl,
FormGroup,
Validators,
UntypedFormControl,
} from '@angular/forms';
import { FileRemoveEvent, FileSelectEvent } from 'primeng/fileupload';
interface UploadEvent {
originalEvent: Event;
files: File[];
}
@Component({
selector: 'file-upload-advanced-demo',
templateUrl: './file-upload-advanced-demo.html',
standalone: true,
imports: [ImportsModule],
providers: [MessageService],
})
export class FileUploadAdvancedDemo {
_fb = inject(FormBuilder);
form = this._fb.group({
files: new UntypedFormControl({ value: null, disabled: false }, [
Validators.required,
]),
});
uploadedFiles: any[] = [];
constructor(private messageService: MessageService) {}
onUpload(event: UploadEvent) {
for (let file of event.files) {
this.uploadedFiles.push(file);
}
this.messageService.add({
severity: 'info',
summary: 'File Uploaded',
detail: '',
});
}
onFilesSelectedToUpload(files: any[]) {
console.log(files);
files.forEach((file) => {});
}
onSelect(event: FileSelectEvent) {
this.form.get('files').setValue(event.currentFiles);
this.form.markAsDirty();
this.onFilesSelectedToUpload(event.currentFiles);
}
onRemove(event: FileRemoveEvent) {
const filesCtrl = this.form.get('files');
const files = filesCtrl.value;
filesCtrl.patchValue(files.filter((file: File) => file !== event.file));
this.onFilesSelectedToUpload(filesCtrl.value);
}
}