I have two functions (One function within the controller and oen function in a service). I want to call the service function from the controller function. After calling teh service function this function calls a database function (using Sequelize).
Controller:
exports.getMilestoneById = async (req, res, next) => {
const milestoneId = req.params.milestoneId;
try{
milestoneService.getMilestoneById(milestoneId)
.then(mielstone => {
console.log("Milestone in tehn: " mielstone)
});
console.log("Milestone: " milestone);
res.status(200).json({message: 'Milestone fetched', milestone: milestone});
} catch (error){
if (!error.statusCode){
error.statusCode = 500;
}
}
}
Service:
exports.getMilestoneById = async (milestoneId) => {
Milestone.findByPk(milestoneId)
.then(milestone => {
console.log("In Service: " milestone)
return milestone.get();
})
.catch(err => {
console.log("Error" err);
});
}
The problem: I don't get a milestone back.
CodePudding user response:
When you are returning the result in this callback:
.then(milestone => {
console.log("In Service: " milestone)
return milestone.get();
})
You are in fact setting the return value for the callback function, not the return value for your service function milestone service.getMilestoneById().
Because your function is an async function, you should use Javascript's async-await syntax, which will only get the value once the promise is resolved.
exports.getMilestoneById = async (milestoneId) => {
const milestone = await Milestone.findByPk(milestoneId)
.catch(err => {
console.log("Error" err);
});
console.log("In Service: " milestone)
return milestone
}
This should be the same for your controller function:
exports.getMilestoneById = async (req, res, next) => {
const milestoneId = req.params.milestoneId;
try{
const milestone = await milestoneService.getMilestoneById(milestoneId)
console.log("Milestone: " milestone);
res.status(200).json({message: 'Milestone fetched', milestone:
milestone});
} catch (error){
if (!error.statusCode){
error.statusCode = 500;
}
}
}
CodePudding user response:
Ok, let's try to put some order here.
Promises Flow
Your code doesn't wait for the Promise response.
milestoneService.getMilestoneById(milestoneId) // <- this returns a promise
// all stuff below here doesn't wait for the promise to complete and can't see its result
console.log("Milestone: " milestone);
res.status(200).json({message: 'Milestone fetched', milestone: milestone});
Instead, writing something like:
milestoneService.getMilestoneById(milestoneId)
.then(mielstone => {
console.log("Milestone in tehn: " mielstone);
// I moved all the stuff that needs to wait in here!!
console.log("Milestone: " milestone);
res.status(200).json({message: 'Milestone fetched', milestone: milestone});
});
This would work as expected.
Async / Await
You added that async before the functions, I'd figure you could put that to good use!
async / await helps you clean the promises flow by letting the wrapping function wait for their results, so writing something like:
const milestone = await milestoneService.getMilestoneById(milestoneId)
console.log("Milestone: " milestone);
res.status(200).json({message: 'Milestone fetched', milestone: milestone});
Would also work as expected.
Returns
... or not! You missed pretty much all returns in your code. As a rule of thumbs try to make every function always return something, especially if it's promises! So like:
exports.getMilestoneById = async (milestoneId) => {
const milestone = await Milestone.findByPk(milestoneId);
return milestone.get();
/* I don't suggest handling the error here, because it doesn't bubble well!
/* If there's an error what would this function return?
}
Then
exports.getMilestoneById = async (req, res, next) => {
const milestoneId = req.params.milestoneId;
try {
const milestone = await milestoneService.getMilestoneById(milestoneId)
console.log("Milestone: " milestone);
// just return this
return res.status(200).json({ message: 'Milestone fetched', milestone });
} catch (error){
if (!error.statusCode){
error.statusCode = 500;
}
// call next with the error!
return next(error);
}
}
