Skip to content

ZouYouShun/ngxf-uploader

Repository files navigation

NPM version

ngxf-uploader

File uploader for Angular 6+, just use Angular HttpClient, no other dependence. GitHub

  • âś… file upload
  • âś… multiple File upload
  • âś… accept support
  • âś… Progress support
  • âś… upload http request support
  • âś… folder upload, thanks for SHANG-TING, more detail about file upload with folder, can view his blog

Stackblitz Example

Stackblitz

Future

[
  {
    "name": "folder name",
    "files": [...files],
  }
]

Description

Select file or Drop, Paste file, and return an Observable. You can custom your behavior use RxJs 7.x .

Provide an sample way for upload by custom options like header, params, fields, file's form name.

Example

Install

npm install ngxf-uploader --save
  • Import HttpClientModule, NgxfUploaderModule into your main AppModule or the module where you want use.
import { provideHttpClient } from '@angular/common/http';
import { provideExperimentalZonelessChangeDetection, model, inject } from '@angular/core';

import { of, catchError, finalize, tap } from 'rxjs';

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { FileError, NgxfDirectoryStructure, NgxfDropDirective, NgxfSelectDirective, NgxfUploaderService, UploadEvent, UploadStatus, NgxfParseDirective } from 'ngxf-uploader';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [NgxfSelectDirective, NgxfDropDirective, NgxfParseDirective],
  templateUrl: './app.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
  progress = 0;
  isUploading = false;
  upload = inject(NgxfUploaderService);

  uploadFile(file: File | File[] | NgxfDirectoryStructure[] | FileError) {
    console.log(file);
    this.isUploading = true;

    if (!(file instanceof File) || Array.isArray(file)) {
      // this.alertError(file);
      this.isUploading = false;
      return;
    }

    this.upload
      .upload({
        url: 'your api url',
        headers: {
          Authorization: 'token',
        }, // Option
        params: {
          test: '123',
        }, // Option
        fields: {
          // Option
          toUrl: 'device',
        },
        filesKey: 'fileKey', // Option
        files: file,
        process: true,
      })
      .pipe(
        tap((event: UploadEvent) => {
          console.log(event);
          this.progress = event.percent || 0;

          if (event.status === UploadStatus.Completed) {
            alert(`This file upload success!`);
          }
        }),
        catchError((err) => {
          console.error(err);
          // alert(`upload fail`);
          return of(null);
        }),
        finalize(() => {
          console.log('end');
        }),
      )
      .subscribe();
  }

  // Do something you want when file error occur.
  alertError(msg: FileError) {
    switch (msg) {
      case FileError.NumError:
        alert('Number Error');
        break;
      case FileError.SizeError:
        alert('Size Error');
        break;
      case FileError.TypeError:
        alert('Type Error');
        break;
    }
  }
}

bootstrapApplication(App, {
  providers: [provideHttpClient(), provideExperimentalZonelessChangeDetection()],
});
  • Add directive in the template where you want to use.
<!-- select file -->
<button (ngxf-select)="uploadFile($event)">Upload Single File</button>

<!-- drop file & parse image -->
<div (ngxf-drop)="uploadFiles($event)" (ngxf-parse)="uploadFiles($event)" [ngxf-validate]="{size: {min: 5000, max:2566621}, skipInvalid: true}" drop-class="drop" accept="image/*" multiple>
  <h3>Drop file and parse image into here or click here to choice file.</h3>
</div>
  • Add NgxfUploaderService in the constructor and create file upload method in the typescript and upload file to server.
import { Component } from '@angular/core';
import { FileError, NgxfUploaderService, UploadEvent, UploadStatus } from 'ngxf-uploader';

@Component({
  selector: 'app-drop-file',
  templateUrl: './drop-file.component.html',
  styleUrls: ['./drop-file.component.scss'],
})
export class DropFileComponent {
  progress = 0;
  isUploading = false;

  constructor(private Upload: NgxfUploaderService) {}

  uploadFile(file: File | FileError): void {
    console.log(file);
    this.isUploading = true;
    if (!(file instanceof File)) {
      this.alertError(file);
      this.isUploading = false;
      return;
    }
    this.Upload.upload({
      url: 'your api url',
      headers: {
        Authorization: 'token',
      }, // Option
      params: {
        test: '123',
      }, // Option
      fields: {
        // Option
        toUrl: 'device',
      },
      filesKey: 'fileKey', // Option
      files: file,
      process: true,
    }).subscribe(
      (event: UploadEvent) => {
        console.log(event);
        this.progress = event.percent;
        if (event.status === UploadStatus.Completed) {
          alert(`This file upload success!`);
        }
      },
      (err) => {
        console.log(err);
      },
      () => {
        this.isUploading = false;
        console.log('complete');
      },
    );
  }

  uploadFiles(files: File[] | FileError): void {
    console.log(files);
    this.isUploading = true;
    if (!(files instanceof Array)) {
      this.alertError(files);
      this.isUploading = false;
      return;
    }
    this.Upload.upload({
      url: 'your api url',
      headers: {
        Authorization: 'token',
      }, // Option
      params: {
        test: '123',
      }, // Option
      fields: {
        // Option
        toUrl: 'device',
      },
      filesKey: 'fileKey', // Option
      files: files,
      process: true, // if you want process event, set process true
    }).subscribe(
      (event: UploadEvent) => {
        console.log(event);
        this.progress = event.percent;
        if (event.status === UploadStatus.Completed) {
          alert(`upload complete!`);
        }
      },
      (err) => {
        console.log(err);
      },
      () => {
        this.isUploading = false;
        console.log('complete');
      },
    );
  }

  // Do something you want when file error occur.
  alertError(msg: FileError) {
    switch (msg) {
      case FileError.NumError:
        alert('Number Error');
        break;
      case FileError.SizeError:
        alert('Size Error');
        break;
      case FileError.TypeError:
        alert('Type Error');
        break;
    }
  }
}

API

Attribute Detail

Attribute necessary(default) type position description
(ngxf-select) yes (Array)=>File or FileError any tag provide a directive that can let you select file upload by click
(ngxf-drop) yes (Array)=>File[] or FileError any tag provide a directive for you to set area can be drop file into
(ngxf-parse) yes (Array)=>File[] or FileError any tag provide a directive for you to set area can be parse file into
[ngxf-validate] no FileOption with (ngxf-drop) and (ngxf-select) file validate with file size, and other options
[drop-class] no('drop') string with (ngxf-drop) and (ngxf-select) when drop on tag, this class will append on it
[accept] no string with (ngxf-drop) and (ngxf-select) accept file type
[multiple] no boolean with (ngxf-drop) and (ngxf-select) is allow multiple file
[folder] no boolean (ngxf-select) is allow select folder file
[structure] no boolean (ngxf-drop) show the structure of all folders and files with the new feature of dragging folders.

Service Upload Method

This method will return an Observable<UploadEvent>, that you can subscribe it, and return a UploadEvent.

upload(d: UploadObject): Observable<UploadEvent>;

Upload Object

export interface UploadObject {
  /** target upload api url */
  url: string;
  /** upload file or files, also support Blob */
  files: File | File[] | Blob | Blob[];
  /**
   * target file key name
   *
   * @default
   * 'file'
   */
  filesKey?: string | string[];
  /** is that need report upload progress,
   *
   * @default
   * false
   */
  process?: boolean;
  /** other fields that you want to attach together */
  fields?: any;
  /** other headers that you want to attach together */
  headers?: { [name: string]: string | string[] } | HttpHeaders;
  /** other params that you want to attach together */
  params?: { [name: string]: string | string[] } | HttpParams;
  /** response type */
  responseType?: 'arraybuffer' | 'blob' | 'json' | 'text';
  /**
   * is that with credentials
   *
   * view more:
   *
   * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
   */
  withCredentials?: boolean;
  /**
   * request api method type,
   *
   * @default
   * POST
   */
  method?: string;
}

Return Object

You can use this object when event return.

export interface UploadEvent {
  /**
   * upload status
   *
   * - `UploadStatus.Uploading`
   * - `UploadStatus.Completed`
   * - `UploadStatus.UploadError`
   * - `UploadStatus.FileNumError`
   */
  status: UploadStatus;
  /** what percent of current upload rate */
  percent: number;
  /** other data you want to attach */
  data?: any;
}

FileOption

export interface FileOption {
  /**
   * check upload file size
   * unit: `Byte`
   */
  size?: {
    /** the smallest bytes */
    min?: number;
    /** the biggest bytes */
    max?: number;
  }; // unit: Byte,
  /**
   * when you upload some files in once, but not throw error when have some file not in the range
   * you can set it to true, let will skip the Invalid file
   *
   * @default false
   */
  skipInvalid?: boolean;
}

FileError

You can use this enum to conclude the file select return.

export const enum FileError {
  /** when number of file Error */
  NumError,
  /** when file accept type Error */
  TypeError,
  /** when file size error */
  SizeError,
}

UploadStatus

You can use this enum to conclude the return Event.

export const enum UploadStatus {
  /** when file is uploading. */
  Uploading,
  /** when upload complete. */
  Completed,
  /** when server error. */
  UploadError,
  /** when no choice file. */
  FileNumError,
}

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy