0

I need to post a PDF file and a FormGroup in one request. I tried passing the PDF as FormData and the FormGroup just as it is, and also to add both to the FormData. I can't figure out how to pass both or what Annotations I need to add in my REST Request.
In my ts:

 onSubmit() {
    const formData = new FormData();
    formData.append('pdfFile', this.myfile);

    this.form.removeControl('pdfFile');
    formData.append('invoice', this.form.value)

    this.http.post("http://localhost:8080/zugferd/matform", formData)
      .subscribe(res => {
        console.log(res);
      });
  }

In my Spring Controller:

@CrossOrigin(origins = "http://localhost:4200")
@PostMapping(value = "/matform")
public void both(@RequestPart("pdfFile") MultipartFile pdfFile, @RequestPart("invoice") MyInvoice invoice ,HttpServletResponse response) throws IOException {
    System.out.println(invoice.getSender().getStreet());
    System.out.println(pdfFile);
}

Edit: found solution:

      onSubmit() {
        const formData = new FormData();
        formData.append('pdfFile', this.myfile);
        this.form.removeControl('pdfFile');
        
        const json = JSON.stringify(this.form.value);
        const blob = new Blob([json], {type: 'application/json'})
        formData.append('form', blob)
        this.http.post("http://localhost:8080/zugferd/matform", formData)
          .subscribe(res => { 
            //stuff
        });
       }
Nazurii
  • 3
  • 3

1 Answers1

0

Looks like you're good on your way with the angular part. I did a similar thing and needed to pass the file as 'file[0]' in order to have my back end (C# with Nancy) pick up the file as a single element of the Files collection.

const formData = new FormData();
formData.append('file[0]', this.file, this.file.name);
formData.append('editObject', JSON.stringify(this.editObject));

const uri = "/v1/someUri";
this.httpService.post(uri, formData, 'json', true)
    .subscribe(() => this.onDataSaved(), err => this.onError("Could not save file.", err));

In the service I think you need to get hold of the entire request and separate the entries based on the boundary (at least I could not find any other way of doing it). I am not familiar with Spring but maybe this C# code can help you on your way;

var contentType = new ContentType(Request.Headers.ContentType);
var boundary = $"--{contentType.Boundary}";

using (var reader = new StreamReader(Request.Body))
{
    var body = reader.ReadToEnd();
    var startTag = "Content-Disposition: form-data; name=\"editObject\"";
    var jsonPart = StringHelper.ValueBetween(body, startTag, boundary);

    var editObject = JsonConvert.DeserializeObject<SomeEditObject>(jsonPart);

    return await ExecuteCommandAsync(commandProcessorAsync, new AddFileCommand(editObject, Request.Files));
}

DaggeJ
  • 2,094
  • 1
  • 10
  • 22
  • Thanks for your reply! I made it work with [Postman](https://i.stack.imgur.com/Fci8n.png), leaving the Controller as it is above. So it gotta work somehow with Angular too, I hope...still trying to figure it out – Nazurii Mar 09 '21 at 10:42