Edit [04.01.2020]
I figuered out, that the string that I am getting "Bad Request" is the message of my error object. (Message is not set).
So when I am changing the API response so that the message contains my actual error object, it is fine.
let error = {error: {}, code: '', message: {error: {}, code: ''}};
if (err.code === 'DUPLICATE_ENTRY') {
error.message.code = 'DUPLICATE_ENTRY';
error.message.error = {
columns: ["name"]
};
}
So we could say, that this fixes my problem, but to be honest, thats not what im expecting. Am I missing something or is this the correct way, how this is supposed to work? Am I really supposed to put my actual error object into a pseudo message block?
Technologies
I am using Angular 8 as Frontend and nest.js 6.12.9 with typeorm as API.
Short description
The problem consists in being unable to parse the API response object within Angular. The error in Angular is just a string saying Bad Request
Setup
API Controller
@Post()
async create(@Query() link: string, @Body() enrollment: Enrollment, @Res() res: Response) {
this.enrollmentService.create(enrollment, link).then(tEntrollment => {
delete tEntrollment.appointment;
res.status(HttpStatus.CREATED).json(tEntrollment);
}).catch((err) => {
let id = this.makeid(10);
console.log(`[${(new Date()).toDateString()} ${(new Date()).toTimeString()}] Code: ${id} - ${err}`);
let error = {error: {}, code: ''};
if (err.code === 'ER_DUP_ENTRY') {
error.code = 'DUPLICATE_ENTRY';
error.error = {
columns: ["name"]
};
} else {
error.error = {
undefined: {
message: "Some error occurred. Please try again later or contact the support",
code: id
}
};
}
res.status(HttpStatus.BAD_REQUEST).json(error);
});
}
On posting an object like
{
"additions": [],
"driver": null,
"passenger": { "requirement": 1 },
"name": "Test",
"comment": ""
}
the controller does, what it is supposed to do. In this case, the name Test is already in use, so the .catch() block handles the rest, and returns an error response with HttpStatus.BAD_REQUEST and the object
{
"error": {
"columns": [
"name"
]
},
"code": "DUPLICATE_ENTRY"
}
Note that this object is fetched by posting the call via Postman. So everything works fine here.
Main Problem
Like mentioned, the problem is, that I am unable to get this response within my angular project.
The call is made by my terminService and looks as follows.
enroll(enrollment: IEnrollmentModel, appointment: IAppointmentModel): Observable<HttpEvent<IEnrollmentModel>> {
const url = `${environment.api.url}enrollment?link=${appointment.link}`;
// const req = new HttpRequest('POST', url, {
// data: enrollment,
// observe: 'response',
// reportProgress: true,
// });
// return this.httpClient.request(req);
return this.httpClient.post<IEnrollmentModel>(url, enrollment, {observe: 'response'});
}
and the handling of this in my ernollment.component.ts looks like this
this.terminService.enroll(output, this.appointment).subscribe(result => {
if (result.type === HttpEventType.Response) {
switch (result.status) {
case HttpStatus.CREATED:
this.router.navigate([`enroll`], {queryParams: {val: this.appointment.link}});
break;
}
}
}, error => {
console.log(error)
switch (error.status) {
case HttpStatus.BAD_REQUEST:
if (error.code === 'DUPLICATE_ENTRY') {
error.error.columns.forEach(fColumn => {
const uppercaseName = fColumn.charAt(0).toUpperCase() + fColumn.substring(1);
const fnName: string = 'get' + uppercaseName;
this[fnName]().setErrors({inUse: true});
}
});
break;
}
}
);
The posted object looks exactely like shown previously. Looking into the Chrome dev tools I can see, that the response from this API call is exactely like I expected it to be.
{"error":{"columns":["name"]},"code":"DUPLICATE_ENTRY"}. This is actually a good sign, but I am unable to get this response within Angular. When logging the error within error => {} I am just getting a string saying Bad Request. I also tried to log error.status error.body error.error and so on, but this just logs undefined, because error is no object. It is just a string.
What am i missing? How can I properly acces and parse the response, including object and HttpStatus returned by my API?
console.log(err.error)andconsole.log(err.error.message);, buterr.erroris still undefined. I also speciefied(err: HttpErrorResponse) => {}instead oferr => {}