J'essaie d'envoyer un formulaire avec un fichier à mon API via Angular 6, mais la publication n'inclut pas le fichier, même si l'objet qui doit être envoyé le fait.
Lorsque je regarde les journaux de la console, je vois ce qui est attendu, montant: "montant", facturefichier: Fichier .... Mais dans la demande sortante, le champ indique facture: {}, et le fichier est maintenant reçu le l'autre côté. Certaines images sont incluses à la fin.
Enfin, mon API me dit que tous les champs sont manquants, mais je pense qu’un autre problème se pose.
Le composant ressemble à ceci:
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);
});
}
}
Suivi par le service qui fournit le poste:
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)
}
}
Et enfin la classe:
export class Invoice {
id: any;
serial: any;
amount: any;
debtor: any;
dateout: any;
expiration: any;
fid: any;
invoicefile: File;
}
Le journal de la console qui semble correct:
Et la demande sortante où le fichier est manquant:
MODIFIER:
Maintenant, le code de service pour create ressemble à ceci:
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)
}
Et la réponse ressemble à ceci. Ça a l'air bizarre pour moi, et je continue à avoir des erreurs de mon back-end, mais c'est une autre question .
Le corps de votre demande POST est en réalité JSON et non en plusieurs parties comme vous le souhaiteriez (malgré ce que dit l'en-tête Content-Type).
Afin de remédier à cela, vous devez créer un objet FormData et l'utiliser dans votre requête:
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)
Supprimez les données multipart/form des en-têtes pour résoudre ce problème
const HttpUploadOptions = {
headers: new HttpHeaders({ "Content-Type": "multipart/form-data" })
}
Solution
const HttpUploadOptions = {
headers: new HttpHeaders({ "Accept": "application/json" })
}
J'avais auparavant celui qui donnait l'erreur
var fromData = new FormData()
fromData.append(...);
this.http.post(apiUrl, {formData})
Je viens de retirer l'objet des accolades et cela a fonctionné
this.http.post(apiUrl, formData);