NgxFlow
The purpose of this package is to create a wrapper for Angular for fileupload using flow.js.
Demo
https://stackblitz.com/edit/ngx-flow-example
You can also find example source code in the src
folder.
Roadmap
✅ upload single file✅ upload multiple files✅ queue management✅ error handling✅ pause / resume upload✅ cancel upload, cancel all uploads✅ upload progress✅ file / directory restrictions✅ drag & drop✅ display uploaded image✅ tests✅ upload right after selecting file✅ run tests using TravisCI✅ demo using Stackblitz✅ support for server side rendering
Install
npm install @flowjs/flow.js @flowjs/ngx-flow
Import in your module:
import { NgxFlowModule, FlowInjectionToken } from '@flowjs/ngx-flow';
import Flow from '@flowjs/flow.js';
@NgModule({
imports: [NgxFlowModule],
providers: [
{
provide: FlowInjectionToken,
useValue: Flow
}
]
})
export class AppModule
We use dependecy injection to provide flow.js library.
How to use
-
Start up server. There is a server example taken from flow.js here in
server
directory. In this repo you can run it usingnpm run server
. -
First you need to initialize ngx-flow directive and export it as for example
flow
variable:<ng-container #flow="flow" [flowConfig]="{target: 'http://localhost:3000/upload'}"></ng-container>
-
Now you can use either directive
flowButton
for select file dialog:<input type="file" flowButton [flow]="flow.flowJs" [flowAttributes]="{accept: 'image/*'}">
Or
flowDrop
for drag&drop feature:<div class="drop-area" flowDrop [flow]="flow.flowJs"> </div>
For both you have to pass
[flow]=flow.flowJs
whereflow
is template variable exported in step 1. -
You can than subscribe to observable of transfers:
<div *ngFor="let transfer of (flow.transfers$ | async).transfers">
-
After adding files you can begin upload using
upload()
method:<button type="button" (click)="flow.upload()" [disabled]="!(flow.somethingToUpload$ | async)">Start upload</button>
transfers$
data look like?
How does Observable flow.transfers$
emits state in form:
{
totalProgress: 0.5,
transfers: [
{
name: "somefile.txt",
flowFile: FlowFile,
progress: number,
error: boolean,
paused: boolean,
success: boolean,
complete: boolean,
currentSpeed: number,
averageSpeed: number,
size: number,
timeRemaining: number,
},
{
name: "uploading.txt",
flowFile: FlowFile,
progress: 0.5,
error: false,
paused: false,
success: false,
complete: false,
currentSpeed: number,
averageSpeed: number,
size: number,
timeRemaining: number,
},
{
name: "failed-to-upload.txt",
flowFile: FlowFile,
progress: number,
error: true,
paused: false,
success: false,
complete: true,
currentSpeed: number,
averageSpeed: number,
size: number,
timeRemaining: number,
}
{
name: "uploaded.txt",
flowFile: FlowFile,
progress: number,
error: false,
paused: false,
success: true,
complete: true,
currentSpeed: number,
averageSpeed: number,
size: number,
timeRemaining: number,
}
],
flow: { /* flow.js instance*/ }
}
FAQ
I need access to flow.js object
You can find it under flow
variable.
<p>Is flowjs supported by the browser? {{flow.flowJs?.support}}</p>
I see flickering when upload is in progress
Use trackBy
for ngFor
:
<div *ngFor="let transfer of (flow.transfers$ | async).transfers; trackBy: trackTransfer">
export class AppComponent {
trackTransfer(transfer: Transfer) {
return transfer.id;
}
}
I need just a single file
Add singleFile: true
to your flow config:
<ng-container #flow="flow" [flowConfig]="{target: 'http://localhost:3000/upload', singleFile: true}"></ng-container>
I want to upload whole directory
Add flowDirectoryOnly="true"
to your button:
<input type="file"
flowButton
[flow]="flow.flowJs"
flowDirectoryOnly="true"
[flowAttributes]="{accept: 'image/*'}">
I want to display image which is going to be uploaded
Use directive flowSrc
:
<div *ngFor="let transfer of (flow.transfers$ | async).transfers">
<img [flowSrc]="transfer">
</div>
How to trigger upload right after picking the file?
Subscribe to events$
. NgxFlow listens for these events: filesSubmitted
, fileRemoved
, fileRetry
, fileProgress
, fileSuccess
, fileError
of flow.js. Event fileSubmitted
is fired when user drops or selects a file.
export class AppComponent implements AfterViewInit, OnDestroy {
@ViewChild('flow')
flow: FlowDirective;
autoUploadSubscription: Subscription;
ngAfterViewInit() {
this.autoUploadSubscription = this.flow.events$.subscribe(event => {
if (event.type === 'filesSubmitted') {
this.flow.upload();
}
});
}
ngOnDestroy() {
this.autoUploadSubscription.unsubscribe();
}
}