it-swarm.com.de

Angular 6 Post-Request mit einem mehrteiligen Formular enthält nicht die angehängte Datei des geposteten Objekts

Ich versuche, ein Formular zusammen mit einer Datei über Angular 6 an meine API zu senden, aber der Beitrag enthält die Datei nicht, obwohl das Objekt, das gesendet werden soll, dies tut.

Wenn ich mir die Konsolenprotokolle anschaue, sehe ich, was erwartet wird, betrag: "betrag", invoicefile: File .... Aber in der ausgehenden Anforderung zeigt das Feld invoicefile: {} an und jetzt wird die Datei empfangen Die andere Seite. Einige Bilder sind am Ende enthalten.

Zuletzt sagt meine API, dass mir alle Felder fehlen, aber ich denke, dass ein anderes Problem besteht.

Die Komponente sieht folgendermaßen aus:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { first } from 'rxjs/operators';
import { FormGroup, FormBuilder, FormControl, Validators, FormArray, ReactiveFormsModule } from '@angular/forms';
import { HttpClient } from '@angular/common/http';

import { AlertService } from '../_services';
import { InvoiceService } from '../_services';
import { Invoice } from '../_models';

@Component({
  selector: 'app-registerinvoice',
  templateUrl: './registerinvoice.component.html',
  styleUrls: ['./registerinvoice.component.css']
})
export class RegisterinvoiceComponent implements OnInit {
  public registerForm: FormGroup;
  public submitted: boolean;

  constructor(
    private router: Router,
    private invoiceService: InvoiceService,
    private alertService: AlertService,
    private http: HttpClient,

  ) { }
  fileToUpload: File = null;

  ngOnInit() {
    this.registerForm = new FormGroup({
      serial: new FormControl('', [<any>Validators.required, <any>Validators.minLength(5)]),
      amount: new FormControl('', [<any>Validators.required, <any>Validators.minLength(4)]),
      debtor: new FormControl('', [<any>Validators.required, <any>Validators.minLength(10)]),
      dateout: new FormControl('', [<any>Validators.required, <any>Validators.minLength(8)]),
      expiration: new FormControl('', [<any>Validators.required, <any>Validators.minLength(8)]),
    });
  }
  handleFileInput(files: FileList){
    this.fileToUpload=files.item(0);
  }

  deliverForm(invoice: Invoice, isValid) {
    this.submitted=true;
    if (!isValid){
      return;
    }
    invoice.invoicefile=this.fileToUpload;
    console.log(invoice);
    console.log(typeof(invoice.invoicefile));
    this.invoiceService.create(invoice)
      .pipe(first())
      .subscribe(
        data => {
          this.alertService.success('Invoice successfully uploaded', true);
          this.router.navigate(['/profile']);
        },
        error => {
          this.alertService.error(error);
        });
  }

}

Gefolgt von dem Dienst, der die Post bereitstellt:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Http } from '@angular/http';
import { Invoice } from '../_models';
import { FormGroup } from '@angular/forms';

const HttpUploadOptions = {
  headers: new HttpHeaders({ "Content-Type": "multipart/form-data" })
}
@Injectable({
  providedIn: 'root'
})
export class InvoiceService {

  constructor(
    private http: HttpClient
  ) { }
  create(invoice: Invoice){
    return this.http.post('/api/v1/invoices/', invoice, HttpUploadOptions)
  }
}

Und zum Schluss die Klasse:

export class Invoice {
    id: any;
    serial: any;
    amount: any;
    debtor: any;
    dateout: any;
    expiration: any;
    fid: any;
    invoicefile: File;
}

Das Konsolenprotokoll, das richtig aussieht: enter image description here

Und die ausgehende Anforderung, bei der die Datei fehlt: enter image description here

BEARBEITEN: 

Nun sieht der Servicecode für create so aus:

create(invoice: Invoice){
    let payload=new FormData();
    payload.append('amount', invoice.amount);
    payload.append('debtor', invoice.debtor);
    payload.append('serial', invoice.serial);
    payload.append('dateout', invoice.dateout);
    payload.append('expiration', invoice.expiration);
    payload.append('invoicefile', invoice.invoicefile);
    return this.http.post('/api/v1/invoices/', payload, HttpUploadOptions)
  }

Und die Antwort sieht so aus. Sieht komisch aus, und ich bekomme immer noch einige Fehler von meinem Backend, aber das ist eine andere Frage . enter image description here

3
Marcus Grass

Ihr POST - Request-Body ist eigentlich JSON, nicht Multipart, wie Sie hoffen (trotz der Inhalts-Header).

Um dies zu beheben, müssen Sie ein FormData-Objekt erstellen und dieses stattdessen in Ihrer Anfrage verwenden:

let input = new FormData();
// Add your values in here
input.append('id', invoice.id);
input.append('invoiceFile', invoice.invoiceFile);
// etc, etc

this.http.post('/api/v1/invoices/', input, HttpUploadOptions)
15
user184994

Entfernen Sie die Multipart-/Formulardaten aus den Kopfzeilen, um dieses Problem zu beheben

const HttpUploadOptions = {
  headers: new HttpHeaders({ "Content-Type": "multipart/form-data" })
}

Lösung

const HttpUploadOptions = {
  headers: new HttpHeaders({ "Accept": "application/json" })
}
1
user2617449

Ich hatte vorher diesen, der Fehler machte

var fromData = new FormData()
fromData.append(...);
this.http.post(apiUrl, {formData})

Ich habe das Objekt einfach von den Zahnspangen entfernt und es hat funktioniert

this.http.post(apiUrl, formData);
0
AbdulRehman