flow-components
flow-components copied to clipboard
Changes done in a StartedListener are not shown
Upload upload = new Upload();
upload.addStartedListener(e -> {
add( new Text("Upload of " + e.getFilename() + " of size " + e.getContentLength() + " started"));
});
When the upload starts, no text is shown. When the upload is abort or completed, the text is shown.
This probably means that the listener is run without access and might thus also cause other interesting issues.
All events are fired and handled by the listeners correctly on the server side: all locks and access are done properly.
The listener code on the server side is executed at the correct time.
The problem is that the listener in this specific case produces some changes in the StateTree instance.
Those changes are sent to the client only in the end of the response handling.
But the input stream is read in the same request dispatching thread so nothing will be sent to the client until stream is completely read.
That's the reason why all listeners shows their result in the very end (on the client side).
Though on the server side they are called at the correct time.
@denis-anisimov Upload should make a visit to server once a file is submitted. This is how previous Vaadin versions worked. Without that, the started listener is almost useless (unless using Push, which I presume "fixes" the issue).
Here is a simple code snippet to test this locally with small files:
Upload upload = new Upload((MultiFileReceiver) new MultiFileReceiver() {
@Override
public OutputStream receiveUpload(String filename, String mimeType) {
return new OutputStream() {
int count;
@Override
public synchronized void write(int b) {
count++;
if(count%10 == 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(MainView.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
};
}
});
upload.addStartedListener(e -> {
System.out.println("Handling upload of " + e.getFileName() + " ("
+ e.getContentLength() + " bytes) started");
Notification.show("This message should pop up when upload has started");
});
upload.addFinishedListener(e -> {
System.out.println("Handling upload of " + e.getFileName() + " ("
+ e.getContentLength() + " bytes) finished");
});
upload.addSucceededListener(e -> {
System.out.println("Handling upload of " + e.getFileName() + " ("
+ e.getContentLength() + " bytes) succeeded");
Notification.show("This message should pop up when upload has succeeded");
});
So we'd need something like this to V10+ too:
https://github.com/vaadin/framework/blob/master/client/src/main/java/com/vaadin/client/ui/VUpload.java#L295-L317
We faced a similar issue (if I understood it correctly), we wanted to disable the buttons while the upload was in progress (right after the upload starts). We used the following workaround and it worked:
uploadComponent.getElement().addEventListener("upload-start",e -> disableButtons());
This is indeed an annoying bug. In our case we have a start listener that sets a flag when an upload is started and an all-finished listener that clears it again. The flag is evaluated in a dialog's validation before a final action is triggered.
This currently doesn't work if e.g. a large file (1GB in our case) is uploaded - the flag is only set when the large upload finishes.
Note: We have tried to leverage Upload::isUploading field for the same use case, but this one isn't updated either until all uploads are done (the listener approach at least works if there are smaller files contained in a multifile upload).
@mlopezFC thanks alot for the workaround.