I have a patch endpoint that takes a body of fields to update, iterates over each field, and updates the correct value. I want to do something send a response once all those things are done, but I do not know how to await a loop of operations. If it was a singular operation I could just add .then(), but that would not work in this case. What is an elegant solution to this?
Code:
const updateUser = (req, res) => {
const db = mongoConnection.getDb();
for (key in req.body) {
db.collection('users').updateOne(
{username: req.query.username},
{$set: {[key]: req.body[key]}}
)
}
// send response once for loop is done
}
CodePudding user response:
I think an easy answer would be hiding the for loop in an async function, then use it in the endpoint.
const updateUserField = async () =>
db.collection("users").updateOne(
{
username: req.query.username,
},
{
$set: { [key]: req.body[key] },
}
);
const updateUserEndpoint = (req, res) => {
for (let field of req.body) {
await updateUserField(field);
}
res.status(200).send('updated');
}
Then, for testing, you could wrap the endpoint with a function that injects the function itself:
const updateUserEndpoint = (userUpdateFunc) => userUpdateFunc(req, res);
This pattern is called dependency injection - when writing unit tests for the endpoint, you'd just replace userUpdateFunc
with whatever mocked function you want to use. This removes the need to monkeypatch the function in the test.