Reputation: 4319
I am trying to create a simple REST API with NodeJS and Express without any database. I have stored all of my data in JSON files. The data is in the form of an array of objects.
I have paths like fund-name/:portId
so I am doing this:
const fundName = require('./json/fund-name.json');
app.get('/fund-details:portId', (req, res) => {
const portId = req.params.portId;
fundDetails.forEach(fund => {
if (fund.portId === portId) {
return res.json(fund);
}
return res.json([]);
});
});
when I hit the url http:localhost:3000/fund-details/1234
, I get the following error:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client at ServerResponse.setHeader (_http_outgoing.js:470:11) at ServerResponse.header (/home/username/Desktop/data-server/node_modules/express/l ib/response.js:767:10)
It works fine when I don't pass any path param to get all the funds. Where am I going wrong??
Upvotes: 6
Views: 19694
Reputation: 2528
This error is because you are using res.send() multiple time in single api call.
Correct way
if(a){
res.send()
}else{
res.send()
}
Wrong way
if(a){
res.send()
res.send()
}else{
res.send()
}
In your code.
app.get('/fund-details:portId', (req, res) => {
const portId = req.params.portId;
fundDetails.forEach(fund => {
if (fund.portId === portId) {
return res.json(fund); // many or single times here
}
return res.json([]); // and here when fund !==portId here
});
});
You can try
app.get('/fund-details:portId', (req, res) => {
const portId = req.params.portId;
var flag
var data = []
fundDetails.forEach(fund => {
if (fund.portId === portId) {
flag=true
data.push(fund)
}
});
if(flag){
res.send(data);
}else{
res.send()
}
});
Upvotes: 17
Reputation: 2605
The method res.json(fund)
is called per each item in fundDetails and then a further res.json([])
method is called. This leads to your response being send back multiple times (which it shouldn't happen, only 1 response per a single api call should be used).
I suggest that you use an array and push back objects with the matching port id and then send the array back to the user when the operation is completed. To be honest, you don't even need the flag variable to check if funds exists or not since if they don't, you empty data array is sent back.
var data = [];
fundDetails.forEach(fund => {
if (fund.portId === portId)
data.push(fund);
});
res.json(data);
Upvotes: 2