Angular Resumable Upload Module
- 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
- 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.
npm install @uploadx/core expressimport { 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);π Full server setup guide β
Contents:
- UploadxOptions
- provideUploadx
- UploadxModule
- Directives
- UploadxService
- UploadState
- UploadxControlEvent
- DI tokens
-
allowedTypesAllowed file types (directive only) -
authorizeReplaces the default Bearer authorization logic(example) -
autoUploadAuto start upload when files added. Default value:true -
storeIncompleteHoursLimit upload lifetime. Default value:24 -
chunkSizeFixed 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 chunked -
maxChunkSizeDynamic chunk size limit -
concurrencySet the maximum parallel uploads. Default value:2 -
endpointURL to create new uploads. Default value:'/upload' -
responseTypeExpected server response type -
headersHeaders to be appended to each HTTP request -
metadataCustom metadata to be added to the uploaded files -
multipleAllow 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
Provides configuration options for standalone app (example).
bootstrapApplication(AppComponent, {
providers: [
provideUploadx({
endpoint: 'http://example.com/upload',
allowedTypes: 'video/*,audio/*',
maxChunkSize: 96 * 1024 * 1024
})
]
});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: []
})π‘ No need to import
UploadxModuleif you do not use theuploadxoruploadxDropdirectives in your application.
<div uploadxDrop>
<label class="file-drop">
<input type="file" [uploadx]="options" [control]="control" (state)="onState($event)" />
</label>
</div>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
File drop directive.
selector: uploadxDrop
π‘ Activates the
.uploadx-drop-activeclass on DnD operations.
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.
π‘ 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.
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';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
}-
UPLOADX_FACTORY_OPTIONS: override default configuration -
UPLOADX_OPTIONS: global options -
UPLOADX_AJAX: override internal ajax lib
Checkout the Demo App or run it on your local machine:
- Run script
npm start - Navigate to
http://localhost:4200/
Run npm run build:pkg to build the lib.
packaged by ng-packagr
For bugs, questions and discussions please use the GitHub Issues.
Pull requests are welcome!
To contribute, please read contributing instructions.
The MIT License (see the LICENSE file for the full text)