Angular Integration
Example code showing how to integrate MultipleUpload with an Angular component using AfterViewInit and ViewChild.
Drag & drop files here
// file-uploader.component.ts
import { Component, AfterViewInit, OnDestroy, ViewChild,
ElementRef, Input, Output, EventEmitter } from '@angular/core';
import MultipleUpload from 'multipleupload';
@Component({
selector: 'app-file-uploader',
template: `
<div #uploaderEl class="mu-uploader">
<button type="button" class="mu-select-btn">Select Files</button>
<input type="file" class="mu-file-input" multiple style="display:none" />
<div class="mu-dropzone">
<div class="mu-dropzone-text">Drag & drop files here</div>
</div>
<div class="mu-queue"></div>
</div>
`
})
export class FileUploaderComponent implements AfterViewInit, OnDestroy {
@ViewChild('uploaderEl') uploaderEl!: ElementRef;
@Input() uploadUrl: string = '/api/upload';
@Output() fileUploaded = new EventEmitter<any>();
private uploader: any;
ngAfterViewInit() {
this.uploader = new MultipleUpload(this.uploaderEl.nativeElement, {
uploadUrl: this.uploadUrl,
onTaskComplete: (task: any) => {
this.fileUploaded.emit(task);
}
});
}
ngOnDestroy() {
if (this.uploader && this.uploader.destroy) {
this.uploader.destroy();
}
}
} // Usage in a parent template <app-file-uploader uploadUrl="/api/upload" (fileUploaded)="onFileUploaded($event)" ></app-file-uploader>
AfterViewInit, not OnInit
The template's DOM does not exist yet when ngOnInit runs, so the container reference is empty. ngAfterViewInit is the first hook where @ViewChild has resolved to a real element, which is what the uploader needs.
Two Angular-specific details
Construct outside the Angular zone if progress events are frequent: each one otherwise triggers change detection across your whole application for a number that changes many times a second. And call destroy() in ngOnDestroy — a routed component is destroyed and recreated freely, and each cycle would otherwise leave an uploader behind.