skip to Main Content

I have a problem with my javascript uploading:
I am using this code:

const handleParameterSearchUpload = async (event) => {
    const files = event.target.files;
    console.log(files);
    const folders = {};

    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      const filePath = file.webkitRelativePath;
      const pathParts = filePath.split('/');

      // If the file is in a subfolder, add the file to the folder's list
      if (pathParts.length > 2) {
        const folderName = encodeURIComponent(pathParts[1]);
        if (!folders[folderName]) {
          folders[folderName] = [];
        }
        folders[folderName].push(file);
      }
    }
    console.log(folders.length);
    // Call processFiles for each folder
    for (const folderName in folders) {
      const folderFiles = folders[folderName];
      await processFiles(folderFiles, true);
      console.log("Processed", folderName);
    }
    parameterSearchInputRef.current.value = "";
  };

to process the files in a folder.

This code is used here:

<input
  type="file"
  webkitdirectory="true"
  style={{ display: 'none' }
  ref={parameterSearchInputRef} 
  onChange={handleParameterSearchUpload} 
/>

Now in this folder there are files and subfolders which are not empty.
Unfortunately I have a problem.
When I upload the folder the files are uploaded, but not the subfolders.
The code is not the problem, because when I rename the folder it works fine, but with this folder name which I upload:

20240118-165159[param.defaults]CombinationParamSearch{sheets.l4_cortex_inh.params.cell.params.v_thresh_[-57.5, -58],sheets.l4_cortex_exc.AfferentConnection.base_weight_[0.0013, 0.0016, 0.0018]}

it doesn’t work.

Unfortunately I will always upload these types of folders to the webpage, how to resolve the issue?
The subfolders have the following name:
SelfSustainedPushPull_ParameterSearch_____base_weight_0.0013_v_thresh_-57.5
SelfSustainedPushPull_ParameterSearch_____base_weight_0.0013_v_thresh_-58

and so on

Unfortunately the base problem is that the subfolders seem like are not getting uploaded, because if I log the console, the subfolders nor the contents inside them are not getting logged.
I really don’t know how to resolve this issue, without using packages like fs or path. Any ideas? Unfortunately I can’t just ask the users to rename the folders, because these folder names are generated from another software.

2

Answers


  1. As far as I know React does not like webkitdirectory and also webkitdirectory might as well be soon deprecated in favor of dropzones. Not really sure about this, but that’s what I’ve read in some discussions about it. Also, I don’t think it is fully compatible with all browsers. See browser compatibility.

    For file uploads with directories and subdirectories, it’s often more effective to use the standard ‘HTML File API’ in combination with DirectoryReader. Another thing to consider is recursively traversing the directory structure.

    Here’s an example on how you can implement it:

    const handleParameterSearchUpload = async (event) => {
      const traverseFiles = async (files) => {
        for (let i = 0; i < files.length; i++) {
          const file = files[i];
          if (file.isDirectory) {
            const directoryReader = file.createReader();
            const entries = await new Promise((resolve) => {
              directoryReader.readEntries(resolve);
            });
            await traverseFiles(entries);
          } else {
            // Process the file
            console.log("Uploading file:", file.name);
            // Upload logic
        }
      };
    
      const files = event.target.files;
      console.log("Uploaded files:", files);
    
      await traverseFiles(files);
    
      // Clear `event.target.value` instead, since we can access the input element
      // directly from the event object. No need for ref.
      event.target.value = "";
    };
    

    Something I also want to mention, just in case, is that you need to use decodeURIComponent to get the original folder name after you encoded it.

    Generally speaking, using FTP or SFTP to upload your files to the server would be an ideal approach for handling folders with multiple subfolders and files. HTTP is not really suited for bulk file transfers. Another solution you might consider is zipping the files before uploading them to the server and then unzipping them on the server side.

    Login or Signup to reply.
  2. Directly uploading folders with Javascript in React can be tricky, especially with special characters in the names. Here’s why and some alternative approaches:

    Challenges with folder uploads:

    • Browser limitations: Standard HTML file upload element (<input type="file">) doesn’t support selecting folders directly. While there’s a webkitdirectory attribute (for Chrome and Safari), it’s not widely supported and might be deprecated.

    Alternative approaches:

    1. Using libraries:

      Libraries like https://react-dropzone.js.org/ can handle folder selection and provide a user-friendly drag-and-drop interface. These libraries often handle special characters by encoding them appropriately before sending to the server.

    2. File API with recursion:

      You can use the HTML5 File API with the DirectoryReader object to traverse a selected directory structure. Here’s a breakdown:

      • Capture the file selection event in your React component.
      • Use event.target.files to access the selected files.
      • Loop through the files:
        • If it’s a directory, use createReader on the file object to create a DirectoryReader.
        • Use readEntries on the reader to get an array of child entries (files and subdirectories).
        • Call a recursive function to process each entry (handle files and repeat for directories).
      • Inside the loop for files, check if it’s a directory using file.isDirectory.
      • For files, you can handle uploading them with special characters by encoding the filenames using encodeURIComponent before sending them to the server. Remember to decode them back on the server-side.

    Important Note:

    Uploading large folder structures with many files might not be suitable for HTTP requests due to limitations. Consider libraries or server-side solutions for handling large uploads.

    const handleFolderUpload = async (event) => {
      const files = event.target.files;
    
      const traverseFiles = async (entries) => {
        for (let i = 0; i < entries.length; i++) {
          const entry = entries[i];
          if (entry.isDirectory) {
            const directoryReader = entry.createReader();
            const subEntries = await new Promise((resolve) => directoryReader.readEntries(resolve));
            await traverseFiles(subEntries);
          } else {
            // Process the file
            const encodedFilename = encodeURIComponent(entry.name);
            console.log("Uploading file:", encodedFilename);
            // Implement your upload logic here, sending encodedFilename to the server
          }
        }
      };
    
      await traverseFiles(files);
      // Clear the file input after processing
      event.target.value = "";
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search