I write an angular based client app for Django API project. One of the endpoints accepts application/x-www-form-urlencoded formatted requests, as it contains both file and string data and I'm pretty sure it works just fine on server-side - I've prepared an application/x-www-form-urlencoded request using POSTMAN:
HEADERS:
Content-Type: application/x-www-form-urlencoded
BODY (form-data):
experiment: http://127.0.0.1:8000/api/v1/experiments/6/
measurement: http://127.0.0.1:8000/api/v1/measurements/4/
variable:
x_axis: X_AXIS
y_axis: Y_AXIS
file_object: // here I've changed the field type and chose the .txt file
Of course the server responded correctly, and file has been added. Here's how the exact request's body looks like:
experiment=http://127.0.0.1:8000/api/v1/experiments/6/measurement=http://127.0.0.1:8000/api/v1/measurements/4/variable=x_axis=os Xy_axis=os Yfile_obj=[object Object]
But now, things are getting more complicated. I try to prepare the same request in Angular using reactive form and HttpClient. Let's say the reactive form itself works as should, but sending the request with 'Content-Type' set to:
- 'application/x-www-form-urlencoded' returns '500 Internal Server Error', and
- 'multipart/data-form' return '415 Unsupported Media Type'
Here's how I send the request:
post(formGroup: FormGroup): Observable<DataFile> {
const httpOption = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded'
})
};
return this.httpClient.post<DataFile>(this.apiEndpoints.datafilesCreateEndpoint(), formGroup.value, httpOption);
}
and here's how the exact request looks like:
{"experiment":"http://127.0.0.1:8000/api/v1/experiments/6/","measurement":"http://127.0.0.1:8000/api/v1/measurements/4/","variable":" ","x_axis":"X AXIS","y_axis":"Y AXIS","file_obj":"C:\\fakepath\\navon.txt"}
Dunno why the request's Form Data is a JSON when I have set the Content-Type to a different one. Could it be a reason of this problem?
@UPDATE Solution
I've removed the httpOptions from post function, to let the Angular pass the Content-Type automatically. Then, instead of passing the FormGroup.value to httpClient's post, I've created the FormData and passed it instead.
Here's how my POST function looks like:
post(experiment: SharedModel, measurement: SharedModel, andOtherDataINeed: any): Observable<DataFile> {
const fd = new FormData();
fd.append('experiment', experiment as any);
...
fd.append('file_obj', file);
return this.httpClient.post<DataFile>(this.apiEndpoints.datafilesCreateEndpoint(), fd);