File Upload > ngx-uploadx
Angular Resumable Upload Module.
ngx-uploadx
Angular Resumable Upload Module
✨ Key Features
- Pause / Resume / Cancel uploads
- Automatic retries with exponential backoff
- Chunked uploads with adaptive chunk size
- Real-time progress, speed & ETA tracking
- Custom headers, metadata, authorization
- Drag & drop support via
uploadxDropdirective
⚡ Quick Start
- Add ngx-uploadx module as dependency:
npm install ngx-uploadx
- Add
uploadxdirective to the component template and provide the required options:
// Standalone component code
//...
import { UploadxDirective, UploadxOptions, UploadState } from 'ngx-uploadx';
@Component({
selector: 'upload-component',
template: ` <input type="file" [uploadx]="options" (state)="onUpload($event)" /> `,
imports: [UploadxDirective]
})
export class UploadComponent {
options: UploadxOptions = { endpoint: 'http://localhost:3000/upload' };
onUpload(state: UploadState) {
console.log(state);
//...
}
}
Please navigate to the src/app sub-folder for more detailed examples.
🖥️ Server-side setup
npm install @uploadx/core express
import { uploadx } from '@uploadx/core';
import express from 'express';
const app = express();
app.use(
'/upload',
uploadx({
directory: './uploads',
maxUploadSize: '20GB',
onComplete: file => {
console.log('File upload complete: ', file);
return file;
}
})
);
app.listen(3002);
📘 API Reference
Contents:
- UploadxOptions
- provideUploadx
- UploadxModule
- Directives
- UploadxService
- UploadState
- UploadxControlEvent
- DI tokens
UploadxOptions
allowedTypesAllowed file types (directive only)authorizeReplaces the default Bearer authorization logic(example)autoUploadAuto start upload when files added. Default value:truestoreIncompleteHoursLimit upload lifetime. Default value:24chunkSizeFixed chunk size. If not specified, the optimal size will be automatically adjusted based on the network speed. If set to0, normal uploading will be used instead of chunkedmaxChunkSizeDynamic chunk size limitconcurrencySet the maximum parallel uploads. Default value:2endpointURL to create new uploads. Default value:'/upload'responseTypeExpected server response typeheadersHeaders to be appended to each HTTP requestmetadataCustom metadata to be added to the uploaded filesmultipleAllow selecting multiple files. Default value:true(directive only)prerequestFunction called before every request (example)retryConfigObject to configure retry settings:maxAttemptsMaximum number of retry attempts. Default value:8shouldRestartCodesUpload not exist and will be restarted. Default value:[404, 410]authErrorCodesIf one of these codes is received, the request will be repeated with an updated authorization token. Default value:[401]shouldRetryCodesRetryable 4xx status codes. Default value:[408, 423, 429, 460]shouldRetryOverrides the built-in function that determines whether the operation should be retriedminDelayMinimum (initial) retry interval. Default value:500maxDelayMaximum retry interval. Default value:50_000onBusyDelayDelay used between retries for non-error responses with missing range/offset. Default value:1000timeoutTime interval after which unfinished requests must be retriedkeepPartialDetermines whether partial chunks should be kept
tokenAuthorization token as astringor function returning astringorPromise<string>uploaderClassUpload API implementation. Built-in:UploaderX(default),Tus. More examples
provideUploadx
Provides configuration options for standalone app (example).
bootstrapApplication(AppComponent, {
providers: [
provideUploadx({
endpoint: 'http://example.com/upload',
allowedTypes: 'video/*,audio/*',
maxChunkSize: 96 * 1024 * 1024
})
]
});
UploadxModule
Adds directives and provide static method withConfig for global configuration
@NgModule({
declarations: [AppComponent, UploadComponent],
imports: [
AppRoutingModule,
BrowserModule,
UploadxModule.withConfig({
allowedTypes: 'image/*,video/*',
endpoint: `${serverUrl}/files?uploadType=uploadx`,
headers: { 'ngsw-bypass': 'true' },
retryConfig: { maxAttempts: 5 }
})
],
providers: [],
bootstrap: [AppComponent],
exports: []
})
:bulb: No need to import
UploadxModuleif you do not use theuploadxoruploadxDropdirectives in your application.
Directives
<div uploadxDrop>
<label class="file-drop">
<input type="file" [uploadx]="options" [control]="control" (state)="onState($event)" />
</label>
</div>
uploadx
File input directive.
selectors: [uploadx], uploadx
Properties:
@Input() uploadx: UploadxOptionsSet directive options@Input() options: UploadxOptionsAlias foruploadxproperty@Input() control: UploadxControlEventControl the uploads@Output() state: EventEmitter<UploadState>Event emitted on upload state change
uploadxDrop
File drop directive.
selector: uploadxDrop
:bulb: Activates the
.uploadx-drop-activeclass on DnD operations.
UploadxService
Programmatic API for upload management. Use it when you need direct control over uploads from component code, dynamic configuration, or deep integration with application state.
init(options?: UploadxOptions): Observable<UploadState>Initializes service. Returns Observable that emits a new value on progress or status changes.
// @example: uploadxOptions: UploadxOptions = { concurrency: 4, endpoint: `${environment.api}/upload`, uploaderClass: Tus }; ngOnInit() { this.uploadService.init(this.uploadxOptions) .subscribe((state: UploadState) => { console.log(state); // ... } }connect(options?: UploadxOptions): Observable<Uploader[]>Initializes service. Returns Observable that emits the current queue.
// @example: @Component({ template: ` <input type="file" uploadx"> <div *ngFor="let item of uploads$ | async">{{item.name}}</div> `, changeDetection: ChangeDetectionStrategy.OnPush }) export class UploadsComponent { uploads$: Observable<Uploader[]>; options: UploadxOptions = { endpoint: `${environment.api}/upload?uploadType=uploadx`, headers: { 'ngsw-bypass': 1 } } constructor(private uploadService: UploadxService) { this.uploads$ = this.uploadService.connect(this.options); }disconnect(): voidTerminate all uploads and clears the queue.
ngOnDestroy(): voidCalled when the service instance is destroyed. Interrupts all uploads and clears the queue and subscriptions.
:bulb: Normally
ngOnDestroy()is never called becauseUploadxServiceis an application-wide service, and uploading will continue even after the upload component is destroyed.handleFiles(files: FileList | File | File[], options = {} as UploadxOptions): void// @example: onFilesSelected(): void { this.uploadService.handleFiles(this.fileInput.nativeElement.files); }Creates uploaders for files and adds them to the upload queue.
control(event: UploadxControlEvent): voidUploads control. Available actions:
upload,cancel,pause,update.// @example: pause(uploadId?: string) { this.uploadService.control({ action: 'pause', uploadId }); } setToken(token: string) { this.uploadService.control({ token }); }request<T = string>(config: AjaxRequestConfig): Promise<AjaxResponse<T>>Make HTTP request with
axioslike interface.// @example: import { AjaxRequestConfig, UploadxService } from 'ngx-uploadx'; class MyService { constructor(private uploadService: UploadxService) {} async fetchUploads() { const config: AjaxRequestConfig = { url: '/api/uploads', method: 'GET' }; const response = await this.uploadService.request(config); return response.items; } }state(): UploadState[]Returns the current state of uploads.
// @example: uploads: UploadState[]; constructor(private uploadService: UploadxService) { // restore background uploads this.uploads = this.uploadService.state(); }queue: Uploader[]Uploaders array.
// @example: export class UploadComponent { state: UploadState; options: UploadxOptions = { concurrency: 1, multiple: false, endpoint: `${environment.api}/upload`, } constructor(private uploadService: UploadxService) { this.state = this.uploadService.queue[0] || {}; }events: Observable<UploadState>Uploads state events.
UploadState
Upload state object emitted by the service:
interface UploadState {
readonly file: File; // Uploaded file
readonly name: string; // Original file name
readonly progress: number; // Progress percentage
readonly remaining: number; // Estimated remaining time
readonly response: ResponseBody; // HTTP response body
readonly responseStatus: number; // HTTP response status code
readonly responseHeaders: Record<string, string>; // HTTP response headers
readonly size: number; // File size in bytes
readonly speed: number; // Upload speed bytes/sec
readonly status: UploadStatus; // Upload status
readonly uploadId: string; // Unique upload id
readonly url: string; // File url
}
type UploadStatus =
| 'added'
| 'queue'
| 'uploading'
| 'complete'
| 'error'
| 'cancelled'
| 'paused'
| 'retry'
| 'updated';
UploadxControlEvent
Control event type for uploadService.control():
interface UploadxControlEvent {
action?: 'upload' | 'cancel' | 'pause' | 'update';
uploadId?: string; // Target upload ID (optional - affects all if not provided)
endpoint?: string; // URL to create new uploads
headers?: RequestHeaders; // Headers to be appended
metadata?: Metadata; // Custom uploads metadata
token?: string; // Authorization token
}
DI tokens
UPLOADX_FACTORY_OPTIONS: override default configurationUPLOADX_OPTIONS: global optionsUPLOADX_AJAX: override internal ajax lib
🧪 Demo
Checkout the Demo App or run it on your local machine:
- Run script
npm start - Navigate to
http://localhost:4200/
🛠️ Build
Run npm run build:pkg to build the lib.
packaged by ng-packagr
🐞 Bugs and Feedback
For bugs, questions and discussions please use the GitHub Issues.
🤝 Contributing
Pull requests are welcome!
To contribute, please read contributing instructions.
📄 License
The MIT License (see the LICENSE file for the full text)