Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File types empty for kml, kmz, and geojson #76

Closed
elmasrya opened this issue Aug 30, 2023 · 3 comments
Closed

File types empty for kml, kmz, and geojson #76

elmasrya opened this issue Aug 30, 2023 · 3 comments

Comments

@elmasrya
Copy link

The file type is an empty string for picking a kmz, kml, or geojson.


Screenshot 2023-08-30 025700


Also there is also no rejection validation for those extensions. Implementing ````accept: ['.kml', '.kmz', '.geojson']```` does not reject files that dont match these extensions.
@Jaaneek
Copy link
Owner

Jaaneek commented Aug 30, 2023

We are not validating at all when using "accept" we are just passing it to the file picker, we might do it in version 2.0 which will be released soon. If you want this behavior right now just write validator yourself, there are examples in readme, let me know if you have any problems

We will take a look into the empty type

@MrKampla
Copy link
Collaborator

@elmasrya We've investigated the issue of missing type property.
This property represents the MIME type of file. It turns out that the package that we rely on for transforming a file input event to actual file object is only supporting a common set of MIME types, which is described here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
As you can see, geojson, kml and kmz extensions are not present on this list, that's why our package just fallbacks to an empty string.

If you need to get the MIME type of file, just get the name property of a file, and then split it by the last dot, so you'll get the file extension. Then you can use a separate package like mime-types, which was specifically built for inferring the MIME type given the file extension.

When it comes to validation, @Jaaneek has already explained that you need to create a custom validator for that. There's no file type validator built into use file picker, so I wrote the one that you need:

import { Validator } from "use-file-picker/validators";

class FileTypeValidator extends Validator {
  constructor(private readonly acceptedFileExtensions: string[]) {
    super();
  }

  validateBeforeParsing(
    _config: UseFilePickerConfig<any>,
    plainFiles: File[]
  ): Promise<void> {
    const fileExtensionErrors = plainFiles.reduce<
      { name: string; reason: string; causedByFile: File }[]
    >((errors, currentFile) => {
        const fileExtension = currentFile.name.split(".").pop();
        if (!fileExtension) {
          return [
            ...errors,
            {
              name: "FileTypeError",
              reason: "FILE_EXTENSION_NOT_FOUND",
              causedByFile: currentFile,
            },
          ];
        }
        if (!this.acceptedFileExtensions.includes(fileExtension)) {
          return [
            ...errors,
            {
              name: "FileTypeError",
              reason: "FILE_TYPE_NOT_ACCEPTED",
              causedByFile: currentFile,
            },
          ];
        }

        return errors;
      },
      []
    );

    return fileExtensionErrors.length > 0
      ? Promise.reject(fileExtensionErrors)
      : Promise.resolve();
  }

  validateAfterParsing(
    _config: UseFilePickerConfig<any>,
    _file: FileWithPath,
    _reader: FileReader
  ): Promise<void> {
    return Promise.resolve();
  }
}

You can later pass it as an argument to the hook:

const { openFilePicker, errors, plainFiles, filesContent } = useFilePicker({
    validators: [
      new FileTypeValidator(["geojson", "kml", "kmz"]),
    ],
    accept: ["*.geojson","*.kml", "*.kmz"],
    readAs: "Text",
  });

I hope it helps! Your use case is quite common, so I'll make sure that this FileTypeValidator is included in the next release of use file picker.

@MrKampla MrKampla mentioned this issue Oct 26, 2023
@MrKampla
Copy link
Collaborator

File type validator was natively shipped with v2.1.1. If you want to use it, just import it from:

import { FileTypeValidator } from 'use-file-picker/validators';

Its API hasn't changed, you can still use it the same way I've already described in this thread above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants