Basically I'm trying to pull out some data from mongodb, modify it and the send it as a response to the client. To modify the data that I need it takes 2 for loops, inside the second loop a function is being called which edits the data and spits out updated version of it, when thats done original arrays data is being modified and so on. I have 2 counters, one is for the parent for loop, second one is for the child, at the end when it the loop ends it checks if it got passed through all parent and child items using counter and if so the response is being sent the modified array. Problem is the response is being called twice every time resulting in a server crash with the following error:
events.js:136
throw er; // Unhandled 'error' event
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at validateHeader (_http_outgoing.js:503:11)
at ServerResponse.setHeader (_http_outgoing.js:510:3)
at ServerResponse.header (/Users/admin/Documents/projects/stalotenisas/server/node_modules/express/lib/response.js:767:10)
at ServerResponse.send (/Users/admin/Documents/projects/stalotenisas/server/node_modules/express/lib/response.js:170:12)
at ServerResponse.json (/Users/admin/Documents/projects/stalotenisas/server/node_modules/express/lib/response.js:267:15)
at calcStats (/Users/admin/Documents/projects/stalotenisas/server/routes/divisions.js:253:23)
at Match.getAll (/Users/admin/Documents/projects/stalotenisas/server/routes/divisions.js:146:7)
at model.Query.<anonymous> (/Users/admin/Documents/projects/stalotenisas/server/node_modules/mongoose/lib/model.js:3928:16)
at /Users/admin/Documents/projects/stalotenisas/server/node_modules/kareem/index.js:297:21
at /Users/admin/Documents/projects/stalotenisas/server/node_modules/kareem/index.js:135:16
at process._tickCallback (internal/process/next_tick.js:150:11)
[nodemon] app crashed - waiting for file changes before starting...
The code:
const divisions = [
{
_id: 0,
name: 'First division',
teams: [
{
name: 'Team A',
players: [
'John',
'Jim',
'Tom',
'Jacob'
]
},
{
name: 'Team B',
players: [
'John',
'Jim',
'Tom',
'Jacob'
]
}
],
players: [],
tournament: false
},
{
_id: 1,
name: 'Second division',
teams: [
{
name: 'Team A',
players: [
'John',
'Jim',
'Tom',
'Jacob'
]
},
{
name: 'Team B',
players: [
'John',
'Jim',
'Tom',
'Jacob'
]
}
],
players: [],
tournament: false
},
{
_id: 2,
name: 'Third division',
teams: [
{
name: 'Team A',
players: [
'John',
'Jim',
'Tom',
'Jacob'
]
},
{
name: 'Team B',
players: [
'John',
'Jim',
'Tom',
'Jacob'
]
}
],
players: [],
tournament: false
}
]
calcTournamentStats = (player, division_id, callback) => {
setTimeout(() => {
callback(null, 'Anthony');
}, 2000);
}
calcStats = (team, division_id, callback) => {
setTimeout(() => {
callback(null, 'Team F');
}, 2000);
}
getDivisionsByLeagueId = (callback) => {
let count = 0;
if (divisions.length === 0) {
return callback('error', null);
}
else {
divisions.forEach((division, dindex) => {
count++;
let inner_count = 0;
if (division.tournament) {
division.players.forEach((player, index) => {
calcTournamentStats(player, division._id, (err, result) => {
inner_count++;
divisions[dindex].players[index] = result;
if (count === divisions.length && inner_count === division.players.length) {
callback(null, 'response which should be caled once');
}
});
});
}
else {
division.teams.forEach((team, index) => {
calcStats(team, division._id, (err, result) => {
inner_count++;
console.log(count +' - '+ divisions.length +' || '+ inner_count +' - '+ division.teams.length);
divisions[dindex].teams[index] = result;
if (count === divisions.length && inner_count === division.teams.length) {
callback(null, 'response which should be caled once');
}
});
});
}
});
}
};
getDivisionsByLeagueId((err, res) => {
console.log(res);
});