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);
}
}