I'm trying to send an HTTP Post request to a REST API I developed using ExpressJS. I'm using Angular's HttpClient using the following service file to send requests:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiJ0ZXN0MiIsImxldmVsIjoxLCJpYXQiOjE1NTYyMDU0OTMsImV4cCI6MTU1NjI5MTg5M30.luqbDb-sSLxsX0LKFTaF6NTYDO4tS6kCI8V_d9pizmA'
})
};
@Injectable({
providedIn: 'root'
})
export class ApiserviceService {
constructor(private http: HttpClient) { }
getData(url: string) {
return this.http.get(url)
}
postData(url: string, data: Object) {
console.log(data);
return this.http.post(url, data, httpOptions)
}
}
Calling the service using the following code:
/* other Component class code */
constructor(private data: ApiserviceService) {}
submit()
{
let url: string =
"http://xxx.xxx/api/hotels/"
+ this.route.snapshot.params.hotelId
+ "/reviews";
this.data.postData(url, this.revForm.value).subscribe(data => {
console.log(data);
this.router.navigate(['/']);
});
}
I had to add an authorization header since the API will reject all requests which do not carry a token.
In the console log just above the http.post statement in the service file, I'm getting the data exactly as desired, a JSON object with all the required parameters being printed on Google Chrome's console. However, for some reason the angular app is sending an empty request.
I was getting a missing values error in the response, so in order to figure out the reason, I added the following line in the API controller along the error handling:
console.log(req.body);
Here's the function from the API:
var _addReview = function(req, res, data) {
data.reviews.push({
name : req.body.name,
rating : parseInt(req.body.rating, 10),
review : req.body.review,
id : req.userid
});
data.save(function(err, hotelUpdated){
if(err) {
console.log(req.body);
res.status(500).json(err);
}
else {
res.status(201).json(hotelUpdated.reviews[hotelUpdated.reviews.length - 1]);
}
});
};
NodeJS's console printed an empty object {}. I tried changing the Content-Type to application/json but still no luck.
I also noticed in the NodeJS console that my Angular app is sending an OPTIONS request before the POST request. I checked online and found that the POST request will only be sent once the OPTIONS request returns a 200 code. However my POST request is being sent, since I am receiving a response. So I believe that the OPTIONS request is getting successful.
My API works perfectly in Postman, even when I send the exact same headers as I am in the Angular app.
Solved the problem by sending the request with Content-Type: application/json instead of application/x-www-form-urlencoded. Apparently Angular was not converting application/x-www-form-urlencoded to json-parseable data like Postman was.