I have a frontend and server-backend, where I send a request to the backend for some book-information. The backend then calls an API for this information and returns it to the frontend. It all works fine at the first request. If I do another request from the frontend it yields the error below.
How can I do such that its possible to keep making a new request from the frontend?
node:internal/errors:478
ErrorCaptureStackTrace(err);
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at new NodeError (node:internal/errors:387:5)
at ServerResponse.setHeader (node:_http_outgoing:644:11)
at ServerResponse.header (/Users/jeff/Documents/myProject/backend/node_modules/express/lib/response.js:794:10)
at ServerResponse.send (/Users/jeff/Documents/myProject/backend/node_modules/express/lib/response.js:174:12)
at ServerResponse.json (/Users/jeff/Documents/myProject/backend/node_modules/express/lib/response.js:278:15)
at file:///Users/jeff/Documents/myProject/backend/controllers/model.js:22:14
at file:///Users/jeff/Documents/myProject/backend/controllers/model.js:63:10
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
code: 'ERR_HTTP_HEADERS_SENT'
}
[nodemon] app crashed - waiting for file changes before starting...
showBooks
is the entry-point for the rest-call from the frontend.
export const showBooks = async (req, res) => {
const books = req.body.books;
await getBooksInfo(books, (err, results) => {
if (err) {
res.send(err);
} else {
res.json(results);
}
});
}
getBooksInfo
is then called, which loops through the provided books
const getBooksInfo = async (books, result) => {
let all_books = [];
books.forEach(async (book) => {
if (book.type == "adventure") {
const on_sale = book.meta.sale;
if (on_sale == true) {
let book_authors = book.meta.authors;
try {
for (const i in book_authors) {
await book_api(book_authors[i].name, (err, results) => {
if (err) {
console.log(err);
} else {
all_books.push(results);
}
});
}
} catch (err) {
console.log(err);
}
}
result(null, { input: all_books });
}
});
}
book_api
is responsible for the getting the information on the external rest-point
export const book_api = async (author_name, result) => {
try {
const response = await axios.get(`https://book-service.com?author=${author_name}`);
const author_info = response.data.author;
let author = {
"name" : author_info.name,
"website" : author_info.website,
};
result(null, author);
} catch (err) {
result(err, null);
}
};
Note that forEach
is not designed for asynchronous operations, try to replace books.forEach(async (book) => ...
with for (const book of books)...