ngx-filepond icon indicating copy to clipboard operation
ngx-filepond copied to clipboard

FilePondComponent doesn't have methods defined in type definitions

Open hogmann opened this issue 3 years ago • 9 comments

Feature Request

https://pqina.nl/filepond/docs/patterns/api/filepond-instance/#methods defines a set of methods that can be called on a filepond instance. These methods are not found in the type definition of the FilepondComponent thus throwing build time errors when trying to access them. Though with some testing these methods work when called. Can these methods be added to the FilePondComponent?

hogmann avatar Oct 30 '20 17:10 hogmann

I'm experiencing the same issue using removeFiles(). I can invoke removeFiles({ revert: false }), but with the current type definitions associated with ngx-filepond TypeScript is unhappy.

mtpultz avatar Oct 30 '20 23:10 mtpultz

Happy to accept a PR 👍

rikschennink avatar Oct 31 '20 10:10 rikschennink

@rikschennink can you point out the type definition file for ngx-filepond? I forked your repo and don't see it and it isn't in DefinitelyTyped repo. I can see the filepond type definitions, and they contain removeFiles definitions - https://github.com/pqina/filepond/blob/master/types/index.d.ts, and I can definitely copy these over onto the FileComponent definitions and submit a PR.

mtpultz avatar Oct 31 '20 22:10 mtpultz

@mtpultz The methods are copied dynamically from the FilePond instance to the FilePondComponent instance (https://github.com/pqina/ngx-filepond/blob/master/src/app/modules/filepond/filepond.component.ts#L140).

So maybe an interface needs to be added to the component (I'm not a TypeScript pro)?

rikschennink avatar Nov 01 '20 09:11 rikschennink

Hi @rikschennink thanks for the reply. I realize they are copied over similar to how the event emitters are mapped. We can use removeFiles({ revert: false }), but TypeScript doesn't recognize the methods existence.

To get around this I added a temporary fix:

const method = 'removeFiles';
this.filePondComponent[method]({ revert: false });

But, updating the type definition of FilePondComponent would fix the issue. Extending FilePondComponent with FilePond's type definition is overkill, but below I copied out the methods that aren't filtered out by ngx-filepond and this would work, but I don't see your type definitions. Are they generated and if so how do you build ngx-filepond so I can see the output with type definitions that are provided through npm?

Example: filepond.component.d.ts

import { ElementRef, SimpleChanges, NgZone } from '@angular/core';
import * as ɵngcc0 from '@angular/core';

import { ActualFileObject, FilePond, FilePondEventPrefixed, FilePondFile, FilePondInitialFile, FilePondOptions, RemoveFileOptions } from 'filepond';

// Set of methods from the FilePond type definition
// @see https://github.com/pqina/filepond/blob/master/types/index.d.ts#L807
export declare class FilePondActions {
  /**
   * Adds a file.
   * @param options.index The index that the file should be added at.
   */
  addFile(source: ActualFileObject | Blob | string, options?: { index?: number } & Partial<FilePondInitialFile["options"]>): Promise<FilePondFile>;
  /**
   * Adds multiple files.
   * @param options.index The index that the files should be added at.
   */
  addFiles(source: ActualFileObject[] | Blob[] | string[], options?: { index: number }): Promise<FilePondFile[]>;
  /**
   * Moves a file. Select file with query and supply target index.
   * @param query The file reference, id, or index.
   * @param index The index to move the file to.
   */
  moveFile(query: FilePondFile | string | number, index: number): void;
  /**
   * Removes a file.
   * @param query The file reference, id, or index. If no query is provided, removes the first file in the list.
   * @param options Options for removal
   */
  removeFile(query?: FilePondFile | string | number, options?: RemoveFileOptions): void;
  /**
   * Removes the first file in the list.
   * @param options Options for removal
   */
  removeFile(options: RemoveFileOptions): void;

  /**
   * Removes files matching the query.
   * @param query Array containing file references, ids, and/or indexes. If no array is provided, all files are removed
   * @param options Options for removal
   */
  removeFiles(query?: Array<FilePondFile | string | number>, options?: RemoveFileOptions): void;
  /**
   * Removes all files.
   * @param options Options for removal
   */
  removeFiles(options: RemoveFileOptions): void;

  /**
   * Processes a file. If no parameter is provided, processes the first file in the list.
   * @param query The file reference, id, or index
   */
  processFile(query?: FilePondFile | string | number): Promise<FilePondFile>;
  /**
   * Processes multiple files. If no parameter is provided, processes all files.
   * @param query The file reference(s), id(s), or index(es)
   */
  processFiles(query?: FilePondFile[] | string[] | number[]): Promise<FilePondFile[]>;

  /**
   * Starts preparing the file matching the given query, returns a Promise, the Promise is resolved with the file item and the output file { file, output }
   * @param query The file reference, id, or index
   */
  prepareFile(query?: FilePondFile | string | number): Promise<{ file: FilePondFile, output: any }>;
  /**
   * Processes multiple files. If no parameter is provided, processes all files.
   * @param query Array containing file reference(s), id(s), or index(es)
   */
  prepareFiles(query?: FilePondFile[] | string[] | number[]): Promise<Array<{ file: FilePondFile, output: any }>>;

  /**
   * Returns a file. If no parameter is provided, returns the first file in the list.
   * @param query The file id, or index
   */
  getFile(query?: string | number): FilePondFile;
  /** Returns all files. */
  getFiles(): FilePondFile[];
  /**
   * Manually trigger the browse files panel.
   *
   * Only works if the call originates from the user.
   */
  browse(): void;
  /**
   * Sort the items in the files list.
   * @param compare The comparison function
   */
  sort(compare: (a: FilePondFile, b: FilePondFile) => number): void;

  /**
   * Adds an event listener to the given event.
   * @param event Name of the event, prefixed with `Filepond:`
   * @param fn Event handler
   */
  addEventListener(event: FilePondEventPrefixed, fn: (e: any) => void): void;
}

export declare class FilePondComponent extends FilePondActions {
  options: Object;
  files: Array<any>;
  private root;
  private zone;
  private pond;
  private handleEvent;
  constructor(root: ElementRef, zone: NgZone);
  ngAfterViewInit(): void;
  ngOnChanges(changes: SimpleChanges): void;
  ngOnDestroy(): void;
  static ɵfac: ɵngcc0.ɵɵFactoryDef<FilePondComponent, never>;
  static ɵcmp: ɵngcc0.ɵɵComponentDefWithMeta<FilePondComponent, "file-pond", never, { "options": "options"; "files": "files"; }, { "oninit": "oninit"; "onwarning": "onwarning"; "onerror": "onerror"; "onactivatefile": "onactivatefile"; "onaddfilestart": "onaddfilestart"; "onaddfileprogress": "onaddfileprogress"; "onaddfile": "onaddfile"; "onprocessfilestart": "onprocessfilestart"; "onprocessfileprogress": "onprocessfileprogress"; "onprocessfileabort": "onprocessfileabort"; "onprocessfilerevert": "onprocessfilerevert"; "onprocessfile": "onprocessfile"; "onprocessfiles": "onprocessfiles"; "onremovefile": "onremovefile"; "onpreparefile": "onpreparefile"; "onupdatefiles": "onupdatefiles"; }, never, never>;
}

mtpultz avatar Nov 02 '20 04:11 mtpultz

@mtpultz I think the definitions are derived from the component, the FilePond types are in the types folder of the core repo. (maybe I misunderstand the question).

rikschennink avatar Nov 02 '20 07:11 rikschennink

@rikschennink yah I wasn't sure where the definitions were being created, but figured out it's ng-packagr.

mtpultz avatar Nov 04 '20 18:11 mtpultz

@mtpultz aha! So it also generates a typescript file, gotcha!

rikschennink avatar Nov 04 '20 18:11 rikschennink

@rikschennink can't seem to run npm run packagr due to issues with a dependency on node-sass on my Mac running Catalina. Will try it on my PC later today and see if I can push up a PR if it works.

mtpultz avatar Nov 04 '20 20:11 mtpultz