3

I'm trying to find a way to get a function requiring a parameter without actually calling the function.

Current broken code example:

const _validations = {
  userID: (req) => check('userID').isString().isUUID('4').run(req),
};

async function (req, res, next) {
  const allReqFields = { ...req.body, ...req.params, ...req.query };

  const fieldsFound = [];
  for (let key of Object.keys(allReqFields)) {
    if (_.has(_validations, key)) {
      fieldsFound.push(_validations[key](req));
    }
  }

  await Promise.all(fieldsFound);

  return next();
},
  function (req, res, next) {
    const errors = validationResult(req);

    if (errors.isEmpty()) {
//ALWAYS HITS HERE
      return next();
    }else{}
}

Code example that works but I don't want:

const _validations = {
  userID: (req) => check('userID').isString().isUUID('4').run(req),
};

async function (req, res, next) {
  const allReqFields = { ...req.body, ...req.params, ...req.query };

  for (let key of Object.keys(allReqFields)) {
    if (_.has(_validations, key)) {
      await _validations[key](req);
    }
  }


  return next();
},
  function (req, res, next) {
    const errors = validationResult(req);

    if (errors.isEmpty()) {
//Correctly hits here
      return next();
    }else{
//Correctly hits here
    }
}

For some context:

The function (req) => check('userID').isString().isUUID('4').run(req), returns a promise.

There are going to be more keys/values inside the _validations object.

Every function inside of _validations will require req to be passed to it.

The end goal is to run all those async functions while having req passed to them.

The issue I'm having now is that fieldsFound.push(_validations[key](req)); is pushing a promise and not the function for me to call later. Which means that fieldsFound is an array of unresolved promises

Any ideas? Thanks!

3
  • I really don't understand what you're trying to do. Can you explain "The end goal is to run all those async functions while having req passed to them." in different words? Commented May 24, 2020 at 7:24
  • @SteveBennett I went ahead and added the issue I'm having. Does that help at all? Commented May 24, 2020 at 7:26
  • Why not fieldsFound.push(_validations[key])? Commented May 25, 2020 at 3:28

2 Answers 2

1
const _validations = {
  userID: () => check('userID').isString().isUUID('4'),
};

Then you push the functions without calling them:

fieldsFound.push(_validations[key]);

And then at the end just call each one with req and await the promises returned:

await Promise.all(fieldsFound.map(func => func().run(req));
Sign up to request clarification or add additional context in comments.

8 Comments

It's not in scope. I went ahead and updating my post!
@DanMossa can't you just run .run(req) at the end?
Say more? Where would I be putting the .run(req) ?
I don't want a foreach, or else I would just be await _validations[key](req); . I want these to be fired all at once.
Is this what you're trying to achieve then? await Promise.all(fieldsFound.map(func => func().run(req));
|
0

You can use function currying.

Currying is a process in functional programming in which we can transform a function with multiple arguments into a sequence of nesting functions. It returns a new function that expects the next argument inline.

Transform your function to something like this.

const _validations = {
  userID: (req) => () => check('userID').isString().isUUID('4').run(req),
};

So you can invoke the function later.

4 Comments

Interesting! Never heard of it before. I updated my code but this doesn't seem to work?
What was the issue?
When I do it with individual awaits, the function gets called correctly because there's another line that checks to see if there were errors and that doesn't get called. I'll update my original post for explanation
As you mentioned in the question, Using above method you can push the functions to the array. eg : fieldsFound.push(_validations[key](req));. So you can call those functions later with the req you passed before.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.