1

I am trying to understand the behavior of async functions and Joi.validate() function. Below is the function I am using to validate user's input.

const Joi = require("joi");

const inputJoiSchema= Joi.object().keys({
  name: Joi.string(),
  email: Joi.string().required(),
  password: Joi.string().required()
});

function validateUser(body) {
  return Joi.validate(body, inputJoiSchema);
}

module.exports = validateUser

validateUser returns proper validate object

{
error:<error/null>,
value:<value/null>,
then: [Function: then],
catch: [Function: catch] }

but for any reason, If I change validateUser function to async function like below it returns Promise instead of object.

async function validateUser(body) {
  return Joi.validate(body, inputJoiSchema);
}

Why so? I am not passing any callback function to Joi.validate and my route handling function looks like below.

router.post("/", async (req, res) => {
  result = validateUser(req.body);
  if(result.error){
      res.status(400).send("Invalid request")
  }
  <some other steps I do after validating>

}
Théo Lavaux
  • 1,364
  • 3
  • 22
  • 46
Chiyaan Suraj
  • 1,021
  • 2
  • 13
  • 27
  • 1
    Does this answer your question? [async/await implicitly returns promise?](https://stackoverflow.com/questions/35302431/async-await-implicitly-returns-promise) – AZ_ Feb 10 '20 at 07:29
  • Yes, That answers my question. So, if you are calling an async function you must always use await. Thanks for the link. – Chiyaan Suraj Feb 10 '20 at 07:37
  • `if you are calling an async function you must always use await.` **No but vice-versa**. If you want to use the `await` (wait for a promise to be resolved) in your function then you mark your function `async` – AZ_ Feb 10 '20 at 07:39

1 Answers1

-1

It is because you had your validateUser as an asynchronous function. You can try this instead

function validateUser(body) {
  return Joi.validate(body, inputJoiSchema);
}

Moreover, you can use .then syntax:

validateUser(req.body).then(x => ...)

Much better, you can proceed to async validation like so

async function validateUser(body) {
  let validation
  try {
   validation = await Joi.validateAsync(body)
  } catch (e) {}
  return validation
}

Source

Karma Blackshaw
  • 880
  • 8
  • 20
  • 1
    `Much better, you can proceed to async validation` why is that better? – AZ_ Feb 10 '20 at 07:35
  • 2
    The solution does not answer OP's question and comment does not answer my question. – AZ_ Feb 10 '20 at 07:37
  • I don't know why I have to answer your question @AZ_, but you can read more about async and sync here https://www.mendix.com/blog/asynchronous-vs-synchronous-programming/#:~:text=Sync%20is%20blocking%20%E2%80%94%20it%20will,is%20slower%20and%20more%20methodical. – Karma Blackshaw Dec 23 '22 at 04:14