Angular File Uploader Directive which provides two directives, which are select and file drag and drop to upload files on server.
npm install ngx-uploader-directivengx-uploader-directive module as dependency to your project.
console
npm install ngx-uploader-directive --save
`
#### Update
`console
npm update ngx-uploader-directive
`
Usage
1. Import NgxUploaderDirectiveModule into your AppModule or in module where you will use it.
`ts
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { NgxUploaderDirectiveModule } from 'ngx-uploader-directive';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
NgxUploaderDirectiveModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
`
or Import NgxUploaderDirectiveModule into your SharedModule. This could be usefull if your project has nested Modules.
`ts
// shared.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { NgxUploaderDirectiveModule } from 'ngx-uploader-directive';
@NgModule({
imports: [
BrowserModule,
AppRoutingModule,
NgxUploaderDirectiveModule
],
providers: [],
bootstrap: [AppComponent]
})
export class SharedModule { }
`
2. Data structures of Input events and upload output events of files.
`ts
/**
* File Upload Options.
*/
export interface IUploadOptions {
requestConcurrency: number; // Number of request can be made at a time.
maxFilesToAddInSingleRequest: number; // Number of files uploaded in single.
allowedFileTypes?: Array; // Allowed file content types.
maxFileUploads?: number; // Max number of files that user can upload
maxFileSize?: number; // Max size of the file in bytes that user can upload.
logs?: boolean; // Flag to show the library logs. Default false
}
/**
* Selected File Object.
*/
export interface ISelectedFile {
requestId: string; // File request id generated by library.
fileIndex: number; // file index of selected files.
name: string; // Name of file.
type: string; // Type of file.
selectedEventType: 'DROP' | 'SELECT'; // Type of selection of file.
progress?: IUploadProgress; // File upload Progress.
nativeFile?: File; // Native File.
response?: any; // Response for the selected file.
}
/**
* File Upload Progress.
*/
export interface IUploadProgress {
status: 'Queue' | 'Uploading' | 'Done' | 'Cancelled'; // Progress stauts.
data?: {
percentage: number; // Progress percentage.
speed: number; // Progress speed.
speedHuman: string; // Progress spped human.
startTime: number | null; // Progress start time.
endTime: number | null; // Progress end time.
eta: number | null; // Progress eta.
etaHuman: string | null; // Progress eta human.
}; // Upload progress data.
}
/**
* Upload Input events that can be emit to ngx-uploader-directive.
*/
export interface IUploadInput {
type: 'uploadAll' | 'uploadFile' | 'cancel' | 'cancelAll' | 'remove' | 'removeAll'; // Input event type.
/**
* Input unique reference number to evalueate unique events.
* Generate using Math.random().
*/
inputReferenceNumber?: number; // Generate number using Math.random() and set it here.
url?: string; // Input url.
method?: string; // Input method.
requestId?: string; // Input id of file to upload.
fieldName?: string; // Input field name.
fileIndex?: number; // Input file index to upload.
file?: ISelectedFile; // Input array selected file.
data?: { [key: string]: string | Blob }; // Input data to pass with file.
headers?: { [key: string]: string }; // Input headers to pass with upload request.
}
/**
* File Upload Output Events that emitted by ngx-uploader-directive.
*/
export interface IUploadOutput {
type: 'init' | 'addedToQueue' | 'allAddedToQueue' | 'uploading' | 'done' | 'start' | 'cancelled' | 'dragOver'
| 'dragOut' | 'drop' | 'removed' | 'removedAll' | 'rejected' | 'error'; // Output events.
requestId?: string; // id of selected file.
files?: Array; // array selected file.
fileSelectedEventType?: 'DROP' | 'SELECT' | 'ALL'; // Type of selection of file.
progress?: IUploadProgress; // Progress
response?: any; // File upload api response.
}
`
Request headers
If you want to pass any request header with file upload, you can set header in upload input event as follows:
- Here I have set Authorization header to pass with request.
`ts
const event: IUploadInput = {
type: 'uploadAll',
inputReferenceNumber: Math.random(),
url: this.uploadUrl,
method: 'POST',
data: {
foo: 'bar'
},
headers: { Authorization: 'bearer ' + 'aetklsndfl' }
};
`
Example
You can always run this working example by cloning this repository and build and run with command in terminal npm start.
Component code
`ts
// tslint:disable: max-line-length
import { Component, EventEmitter } from '@angular/core';
import { IUploadOptions, ISelectedFile, IUploadInput, IUploadOutput } from 'ngx-uploader-directive';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'ngx-uploader-directive';
options: IUploadOptions;
files: Array;
uploadInput: EventEmitter;
dragOver: boolean;
uploadUrl = 'upload url';
/**
* Default Constructor
*/
constructor() {
this.options = { requestConcurrency: 1, maxFilesToAddInSingleRequest: 10, maxFileUploads: 5, maxFileSize: 1000000, logs: true };
this.files = new Array();
this.uploadInput = new EventEmitter();
}
/**
* Upload output events.
* @param output IUploadOutput Model on output.
*/
onUploadOutput(output: IUploadOutput): void {
console.log(output);
switch (output.type) {
case 'init':
this.files = new Array();
break;
case 'allAddedToQueue':
// uncomment this if you want to auto upload files when added
// this.startUpload();
break;
case 'addedToQueue':
this.files = this.files.concat(output.files);
break;
case 'start':
// uploading start
break;
case 'uploading':
this.files = this.updateFiles(this.files, output.files, output.progress, 'UPDATE');
console.log(this.files);
break;
case 'removed':
this.files = this.updateFiles(this.files, output.files, output.progress, 'REMOVE');
console.log(this.files);
break;
case 'removedAll':
this.files = new Array();
console.log(this.files);
break;
case 'dragOver':
this.dragOver = true;
break;
case 'dragOut':
case 'drop':
this.dragOver = false;
break;
case 'done':
// The files are uploaded
this.files = this.updateFiles(this.files, output.files, output.progress, 'UPDATE');
console.log(this.files);
break;
}
}
/**
* Update files on output events
* @param currentFiles Current Files Array
* @param updatedFiles Updated Files Array
* @param progress File progress
* @param action Remove or Update
*/
updateFiles(currentFiles: Array, updatedFiles: Array, progress: IUploadProgress, action: 'REMOVE' | 'UPDATE') {
if (updatedFiles !== undefined) {
if (action === 'UPDATE') {
updatedFiles.forEach(updateFile => {
currentFiles.forEach(
(currentFile, currentFileIndex, currentFilesArray) => {
if (currentFile.name === updateFile.name) {
currentFilesArray[currentFileIndex] = updateFile;
if (progress !== undefined) {
currentFilesArray[currentFileIndex].progress = progress;
}
}
}
);
});
} else if (action === 'REMOVE') {
if (updatedFiles.length > 0) {
currentFiles = currentFiles.filter((file) => file.requestId !== updatedFiles[0].requestId);
} else {
currentFiles = updatedFiles;
}
}
}
return currentFiles;
}
/**
* Start Upload
*/
startUpload(): void {
if (this.files.length > 0) {
this.formData.append('fileHasHeader', 'false');
this.formData.append('delimiter', ',');
const event: IUploadInput = {
type: 'uploadAll',
inputReferenceNumber: Math.random(),
url: this.uploadUrl,
method: 'POST',
data: {
foo: 'bar'
},
headers: { Authorization: 'bearer ' + 'aetklsndfl' }
};
this.uploadInput.emit(event);
} else {
console.error('No files selected');
}
}
/**
* Cancel file uploads.
* @param requestId RequestId.
*/
cancelUpload(requestId: string): void {
this.uploadInput.emit({ type: 'cancel', inputReferenceNumber: Math.random(), requestId });
}
/**
* Remoce files.
* @param requestId Request id
*/
removeFile(requestId: string): void {
console.log(requestId);
this.uploadInput.emit({ type: 'remove', inputReferenceNumber: Math.random(), requestId });
}
/**
* Remoce all file uploads.
*/
removeAllFiles(): void {
this.uploadInput.emit({ type: 'removeAll', inputReferenceNumber: Math.random() });
}
}
`
Html code
`html
[uploadInput]="uploadInput" [ngClass]="{ 'is-drop-over': dragOver }">
Drag & Drop
Running demo on local machine
`console
npm install
npm start
`
Read more
Medium.com
Changelog
Changelog
Contributing
> To get started...
1. 🍴 Fork this repo!
2. 👯 Clone this repo to your local machine using https://github.com/jayprajapati857/ngx-uploader-directive.git`