Handling Uploaded Files

Hello! I’m trying to use the Upload component to upload a single image. I read the documentation and the options feel a little limited.

The java only option only works on vaadin-flow apparently, so I tried the web component option. I successfully sent the image to an API I made, but I’m unable to then save it to a postgres sql DB im using (error in annexed pic). I’m querying a byte array to a BYTEA in the DB, it should work but it doesn’t.

Anyway, my actual question is what would be the fastest way to save the image in a persistent way without using an API if possible, I dont even mind saving it locally.
unknown.png

There isn’t a Hilla specific way of handling file uploads yet. You can create a spring controller for handling the file https://spring.io/guides/gs/uploading-files/

There is a cookbook recipe to show how to do that: https://cookbook.vaadin.com/client-side-upload

You create a REST controller:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
public class FileUploadEndpoint {

    @PostMapping("/api/fileupload")
    public void handleFileUpload(@RequestParam("file") MultipartFile uploadedFile) {
        /* Here you can do something with the uploaded file. For example:
        File file = new File(System.getProperty("user.dir") + "/uploadedFile");
        uploadedFile.transferTo(file);
         */
    }
}

Then from the client side you can call this like so:

@customElement("client-side-upload")
export class UploadView extends VerticalLayout {

  render() {
    return html`
      <vaadin-upload target="api/fileupload" @upload-response=${this.handleResponse}></vaadin-upload>
    `;
  }

  handleResponse(e: UploadResponseEvent){
    if (e.detail.xhr.status == 200) {
      Notification.show("Upload success!")
    } else {
      Notification.show("Oops, something went wrong.")
    }
  }
}

Thank you both for answering! I’ve tried similar things to what your suggesting, I’m gonna try to do them again with this new information.

But I also wanted to know, short answer, can you save files locally directly from the web component Upload in hilla? Like in the java only option here:
https://vaadin.com/docs/latest/components/upload
, but without vaadin-flow?

No, because the Hilla upload component runs in the browser without direct access to the server. You need to pass the file to the server and handle it there

Oh ok, thank you very much

Sorry to interrupt this discussion, but in my opinion you should do a rework to the vaadin upload component, it doesn’t make sense that the only way to obtain the data from the file inserted in this component is through an api, right now the html input is more functional than this component in this aspect, because we can get the data directly in the same typescript page

So you’re saying you would like to handle the file on the client instead of uploading it to a server?

You can add a upload-before event listener on it and then get the file from uploadEvent.detail.file. You’ll want to call uploadEvent.preventDefault() to avoid sending an xhr request

And how can we save the file in a directory like C:/Users/user/Documents after that?

I’m not sure I understand what you’re trying to accomplish. Let the user save the file again back to their computer?

Yes

I assume you have the file as a File or a Blob? If so, I think you should be able to use URL.createObjectURL() and use that as href for a link URL: createObjectURL() static method - Web APIs | MDN

My objective is to save it in the \src\main\resources\META-INF\resources\images path

Hm. That’s a very different use case. That’s saving the file on the server, not the users’s computer

In that case you would need to send the file to the server via a controller as discussed above

But what I would like to do is to send it to a endpoint java, not a controller

I’m thinking of either save it in that file path or send it to a postgres sql database