Search code examples
javascriptarraysreactjstypescriptchunks

Split array of files in N chunks


I have an array of files and I have to split it in chunks based on the file size, in this way:

[10MB image, 5MB image, 5MB image] with max size of 20MB wouldn’t really require split but [10MB, 10MB, 15MB] would be split to [10MB, 10MB] and [15MB]

Then I have to function that takes the files and put them into a formdata to send it to the endpoint.

what I want to do is to return an array of FormData containing the chunks needed.

How can I achieve to that?

this is the current function:

const newImagesToEndpoint = (newFiles: NewImagesInterface[]) => {
    const newImages = new FormData();
    newFiles.forEach(img => {
      newImages.append('images[]', (img.file as unknown) as File);
    });
    return newImages;
  };

Solution

  • Your question isn't that clear. I understand what you mean by split is send from client to server via multiple http calls, but not split an individual file ?

    Assuming NewImagesInterface has a size: number field, something like this then ?

    function sendChunks(images: NewImagesInterface[], limit = 20e6): FormData[] {
      const out: FormData[] = [], chunkSize = 0;
      for(const img of images) {
        if(img.size > limit)
          throw new Error('each individual image must be < ' + limit);
        if(!out.length || chunkSize + img.size > limit) {
          chunkSize = 0;
          out.push(new FormData[]);
        }
        out[out.length-1].append('images[]', (img.file as unknown) as File);
        chunkSize += img.size;
        return out;
    };
    

    Also please pay attention to types, that's the main point of typescript after all. If you want to output an array of FormData then the return type of your function must be FormData[]. The means your function will have at some point to build and return an array. If you think like that, starting from the type requirements and applying them to how you build your code, it will help you come up with a solution.