call javascript object method using partial arguments from outer scope

Viewed 38

I have a getValidators function which returns an object with validator methods:

export function getValidators()  {

  return {
    required: (node, value, [mark='', falsy=[undefined, '']]) => {
      const notValid = falsy.includes(value);
      return setNotValid(node, notValid, mark);
    },
    // ... other validator functions ...
  };
};

All the validator functions have three arguments: node, value and an array: args

I can run the validator function:

let validator = 'required';
let validators = getValidators()
let result = validators[validator](node, value, args);

But I like to run the modified validator function below using the arguments node and value from some outer scope:

export function getValidators()  {

  return {
    required: ([mark='', falsy=[undefined, '']]) => {
      const notValid = falsy.includes(value);
      return setNotValid(node, notValid, mark);
    },
    // ...
  };
};

And like to run it as shown below:

// ... node and value args passed in from outer scope ...?
let result = validators[validator](args);

Update: I cannot use getValidators(node, value) because getValidators will be called first to add additional validator functions.

let validators = getValidators();
validators[method] = aValidatorFunc;
.....
.....
function runValidators() {
  .....
  // use the updated validators instance to run the validators
  for (let validator of .....) { 
     // node and value will change in this loop as well
     ... 
     let result = validators[validator](args);
  }
  ...
}
2 Answers

Don't know if that is what you mean, but you can pass them in from the outer functions' scope like so:

export function getValidators(node, value)  { // Put them in the argument list here
  return {
    required: ([mark='', falsy=[undefined, '']]) => {
      const notValid = falsy.includes(value);
      return setNotValid(node, notValid, mark);
    },
    //...
  };
};
let validator = 'required';
let validators = getValidators(node, value); // Pass your node and value to the outer function

// Now call it like you wanted to call it:
let result = validators[validator](args);

Found a kind of solution using bind(this):

let validators = getValidators();
validators[method] = aValidatorFunc;
.....
.....
function runValidators() {
  .....
  // use the updated validators instance to run the validators
  for (let validator of .....) { 
     // node and value will change in this loop as well
     ...
     const validatorFunc = validators[validator].bind({node, value})  // bind this
     // or with call with a given this as firtst argument: 
     // const validatorFunc = validators[validator].call({node, value}, args); 

     let result = validatorFunc(args);
  }
  ...
}

With bind we cannot use an arrow function, so to use 'this':

export function getValidators()  {

  return {
    required: function([mark='', falsy=[undefined, '']]) {  // function
      const notValid = falsy.includes(this.value);
      return setNotValid(this.node, notValid, mark);
    },
    // ...
  };
};
Related