Search code examples
javascriptreactjsreduxduplicatesredux-form

Field array validation for not allowing duplicate values


i have implemented a field array component using redux form. In my field array i have some validations for not containing for example letters in my inputs. My validation function is this:

const validateFieldArray = (values) => {
  const errors = {
    [LEGO_AMKA_ARRAY]: []
  };
  if (values.get(LEGO_AMKA_ARRAY)) {
    const amkas = values.get(LEGO_AMKA_ARRAY);
    amkas.forEach((field, index) => {
      const amkasErrors = {};
      const amkaField = field.get(AMKA_FIELD);
      if (!amkaField) {
        amkasErrors[AMKA_FIELD] = 'error.required';
        errors[LEGO_AMKA_ARRAY][index] = amkasErrors;
      } else if (onlyNumeric(amkaField) !== undefined) {
        amkasErrors[AMKA_FIELD] = 'error.numbers.allowed';
        errors[LEGO_AMKA_ARRAY][index] = amkasErrors;
      }
    });
  }
  return errors;
};

i want to add a validation for not allowing duplicate entries. If i enter a value which was entered in a previous field i must not allow this. How can i do this?

Thanks!


Solution

  • You can create a dictionary of each value and its occurrences in your array of values using reduce (note - you may need to use map before the reduce, i am not sure how your array structure looks like)

    const dictOccurrences = values.get(LEGO_AMKA_ARRAY).reduce((acc, curr) => ({
        ...acc,
        [curr]: acc[curr] ? acc[curr] + 1 : 1,
    }), {});
    

    then inside your code:

    const validateFieldArray = (values) => {
      const errors = {
        [LEGO_AMKA_ARRAY]: []
      };
      if (values.get(LEGO_AMKA_ARRAY)) {
        const amkas = values.get(LEGO_AMKA_ARRAY);
        const dictOccurrences = amkas.reduce((acc, curr) => ({
        ...acc,
        [curr]: acc[curr] ? acc[curr] + 1 : 1,
    }), {});
        amkas.forEach((field, index) => {
          const amkasErrors = {};
          const amkaField = field.get(AMKA_FIELD);
          if (!amkaField) {
            amkasErrors[AMKA_FIELD] = 'error.required';
            errors[LEGO_AMKA_ARRAY][index] = amkasErrors;
          } else if (onlyNumeric(amkaField) !== undefined) {
            amkasErrors[AMKA_FIELD] = 'error.numbers.allowed';
          }
          if (dictOccurrences[amkaField] > 1) {
            amkasErrors[AMKA_FIELD] = 'error.duplicate';
          }
          errors[LEGO_AMKA_ARRAY][index] = amkasErrors;
        });
      }
      return errors;
    };