Multi File Upload in flow - how to know when all files are finished?

In Vaadin 8, I used the [MultiFileUpload]
(https://vaadin.com/directory/component/multifileupload) add-on, which had a very useful AllUploadFinishedHandler.

In Vaadin Flow, I believe I’ll have to use the Upload, which is able to handle multiple files but I can not find a way to find out when all files are finished uploading.

I am using the Upload like this:

// UploadPojo is a very simple pojo class holding a File, a fileName, a mimeType and a length
private Collection<UploadPojo> unprocessedUploads = new HashSet<>();
Upload uploadBtn = new Upload(buffer); // buffer is of type MultiFileMemoryBuffer
uploadBtn.addSucceededListener(event -> {
	File file = null;
	try {
		file = File.createTempFile("tmp_upload", null);
		FileUtils.copyInputStreamToFile(buffer.getInputStream(event.getFileName()), file);
	} catch (IOException e) {
		e.printStackTrace();
	}
	unprocessedUploads.add(new UploadPojo(file, event.getFileName(), event.getMIMEType(), event.getContentLength()));
});
uploadBtn.setMaxFiles(10);
Button actualReuploadButton = new Button("Upload files", VaadinIcon.UPLOAD.create());
actualReuploadButton.setWidth("100%");
uploadBtn.setUploadButton(actualReuploadButton);

This code collects all uploaded files, which I want to process all at the same time when all files are finished. But how do I know when this time has come? The SucceededEvent has no information if it was the last file or similar, and the Upload has no Event similar to the AllUploadFinishedHandler of the MultiFileUpload add-on.

The reason why I need this is because after all uploads are finished, I want to run a Thread in the background where it iterates over all uploads. Creating a separate Thread for each upload is not an option.

Hi =)
Before starting the upload, you could count how many items will be uploaded and in the succeededListener, count how many items have been successfully uploaded. If the 2 counts match, launch your thread.
The buffer has a getFiles() method which could be useful.
(just an idea)

Hey, using buffer.getFiles().size() is a great idea to find out how many files are being uploaded. Thank you

It works! Thanks for your input, Chris. This is the working code:

private Integer uploadedFilesIndex = 0;
...
uploadBtn.addSucceededListener(event -> {
	File file = null;
	try {
		file = File.createTempFile("tmp_upload", null);
		FileUtils.copyInputStreamToFile(buffer.getInputStream(event.getFileName()), file);
	} catch (IOException e) {
		e.printStackTrace();
	}
	unprocessedUploads.add(new UploadPojo(file, event.getFileName(), event.getMIMEType(), event.getContentLength()));
	uploadedFilesIndex++;
	if(uploadedFilesIndex.equals(buffer.getFiles().size())){
		importAllUnprocessedUploads();
	}
});
private void importAllUnprocessedUploads(){
    // Reset upload stuff so the user can upload a second batch right after
	buffer = new MultifileMemoryBuffer();
	uploadedFilesIndex = 0;
	
	// spawn new Thread doing the hard import work
		// process each uploaded file here, all uploads are stored in var unprocessedUploads
}

:smiley:

Actually, This does not work!

Because when a succeededEvent fires, it does not mean that all files have already been uploaded and the buffer does not yet contain all files. Therefore, my function importAllUnprocessedUploads() is called multiple times, resulting in multiple Imports of the same files (alongside other errors like push errors because multiple Threads will then try to access/modify the same UI).

I can see 2 workarounds, but they feel really dirty!
-add another TextField next to the upload where the user has to say how many files they want to upload. instead of checking if(uploadedFilesIndex.equals(buffer.getFiles().size())){ I can now check for if(uploadedFilesIndex.equals(Integer.parseInt(howManyUploadsTextField.getValue()))){ .

-at the very start of importAllUnprocessedUploads() sleep the Thread for let’s say 5 seconds and then check if there are now more files in the buffer. if that’s the case, fast return and don’t start the import.

Update: Since Vaadin 14.1.0 the Upload component now has the method addAllFinishedListener(ComponentEventListener<AllFinishedEvent> listener). It is made exactly for this. Only once all files are finished uploading will this listener be invoked.