1

I have an array of reasons a password has failed validation:

const failures = schema.validate(password.value, { list: true });
console.log(failues);
// => [ 'min', 'uppercase', 'digits' ]

I also have an array of objects. The key is always a potential value of the failures array:

const msg = [
  { key: 'min', message: 'minimum' },
  { key: 'max', message: 'maximum' },
  { key: 'uppercase', message: 'need a uppercase' },
  { key: 'lowercase', message: 'need a lowercase' },
  { key: 'digits', message: 'must have digits' },
  { key: 'spaces', message: 'no spaces' },
  { key: 'oneOf', message: 'is not one of' },
];

I want to map over the failures array and return the relevant message from msg to display a more coherent error message.

4 Answers 4

2

For each value in failures, pull the corresponding item from msg. However, may I suggest creating msg as a dict?

const msg = {
  'min': 'minimum',
  'max': 'maximum',
  ...
};

This will make it easier to do this.

failures.forEach((failure) => {
  if (failure in msg) {
    console.log(msg[failure]);
  }
});
Sign up to request clarification or add additional context in comments.

1 Comment

Works a treat. Thank you :)
2
const failures = schema.validate(password.value, { list: true });
console.log(failures);
// => [ 'min', 'uppercase', 'digits' ]

const msg = [
  { key: 'min', message: 'minimum' },
  { key: 'max', message: 'maximum' },
  { key: 'uppercase', message: 'need a uppercase' },
  { key: 'lowercase', message: 'need a lowercase' },
  { key: 'digits', message: 'must have digits' },
  { key: 'spaces', message: 'no spaces' },
  { key: 'oneOf', message: 'is not one of' },
];

const listOfMessages = msgs
  .filter(msg => failures.includes(msg.key)) // Get the appropriate object matching the error
  .map(msg => msg.message) // Only get the message

console.log(listOfMessages) // ['minimum', 'need a uppercase', 'must have digits']

Comments

1

You can use array.filter() and array.map() to achieve what you want:

const messages = msg.filter(r=>failures.indexOf(r.key)!==-1).map(r=>r.message)// ["minimum", "need a uppercase", "must have digits"]

What you do with it from here is up to you, as even if you join the messages array, it doesn't form a coherent sentence. I also agree with the recommendation above to switch to a Dict like Object instead of the array of objects you are using now.

Comments

0

// this is a very verbose way to store this information, also hard to fetch by key
const msg = [
  { key: 'min', message: 'minimum' },
  { key: 'max', message: 'maximum' },
  { key: 'uppercase', message: 'need a uppercase' },
  { key: 'lowercase', message: 'need a lowercase' },
  { key: 'digits', message: 'must have digits' },
  { key: 'spaces', message: 'no spaces' },
  { key: 'oneOf', message: 'is not one of' },
];

const failures = [
  'min',
  'uppercase',
  'digits',
  'something-not-mapped'
];


// better use a map
const msg2 = msg.reduce((acc, item) => {
  acc[item.key] = item.message;
  return acc;
}, {});
console.log("msg2:", msg2);

// now you can do:
console.log("mapped failures:", failures.map(key => msg2[key] || key));
.as-console-wrapper{top:0;max-height:100%!important}

I think with the comments, this code is self-explanatory.

Comments

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.