Using Array.Reduce to Streamline Your JavaScript Object Validations
Tags: javascript, webdev, tutorial, programming
Published: 2020-04-27 12:50:27

---
title: Using Array.Reduce to Streamline Your JavaScript Object Validations
published: true
description: Object validation in JavaScript can be tedious if you don't have a good framework in place. In this post, we'll use the `Array.reduce` method to make object validation feel like a treat!
tags: javascript, webdev, tutorial, programming
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/an0lcn4s0tuod5f0rar1.png
---

Object validation in JavaScript can be tedious if you don't have a good framework in place. In this post, we'll use the `Array.reduce` method to make object validation feel like a treat!

# Manual Validations

Let's say we have a `user` object and several criteria that need to pass to make it valid. Here are the properties and the criteria that they must meet:

|prop|criteria|
|---|---|
|name|Longer than 2 characters|
|password|Longer than 8 characters|
|confirmPassword|Matches the password|
|age|18 or greater|

If we were to take a somewhat manual approach to validation, we might write something like this:

```javascript
const user = {
  name: "Bob",
  password: "kaBob123",
  confirmPassword: "kaBob123",
  age: 19,
};

const errors = [];

if (user.name.length < 2) {
  errors.push("User's name is too short");
}

if (user.password.length < 8) {
  errors.push("User's password is too short");
}

if (user.password !== user.confirmPassword) {
  errors.push("Password and confirmation do not match");
}

if (user.age < 18) {
  errors.push("User must be at least 18 years old");
}

const isValid = errors.length === 0;
```

Our `errors` array would get populated with any validation errors and, if the array had a length greater than 0, our `isValid` variable would be `false`.

# Creating a Validation Framework

While this works alright for a small number of validations, I tend to prefer organizing larger sets of rules in an array, and using the `reduce` method to determine if there are errors:

```javascript
// Validation rules
const rules = [
  {
    test: (user) => user.name.length > 2,
    message: "User's name is too short",
  },
  {
    test: (user) => user.password.length >= 8,
    message: "User's password is too short",
  },
  {
    test: (user) => user.password === user.confirmPassword,
    message: "Password and confirmation do not match",
  },
  {
    test: (user) => user.age >= 18,
    message: "User must be at least 18 years old",
  },
];

// Test object against rules
const errors = rules.reduce((errs, rule) => {
  const result = rule.test(user);
  if (result === false) {
    errs.push(rule.message);
  }
  return errs;
}, []);

const isValid = errors.length === 0;
```

Now, we have a consistent interface and can add rules just be adding additional objects to our array!

# Creating a Reusable Validation Function

To extend the utility of our validator, we can create a function that takes an object, a set of rules, and returns errors and validation status. Let's create that function.

```javascript
const validate = (obj, rules) => {
  const errors = rules.reduce((errs, rule) => {
    const result = rule.test(obj);
    if (result === false) {
      errs.push(rule.message);
    }
    return errs;
  }, []);

  return {
    errors,
    isValid: errors.length === 0
  }
}
```

Now, we can use this function wherever we need to validate an object! Let's try with our previous example and use a user object that's not quite valid:

```javascript
// Invalid user object
const user = {
  name: "Bob",
  password: "kaBob123",
  confirmPassword: "kaBob12",
  age: 17,
};

// Validation rules
const rules = [
  {
    test: (user) => user.name.length > 2,
    message: "User's name is too short",
  },
  {
    test: (user) => user.password.length >= 8,
    message: "User's password is too short",
  },
  {
    test: (user) => user.password === user.confirmPassword,
    message: "Password and confirmation do not match",
  },
  {
    test: (user) => user.age >= 18,
    message: "User must be at least 18 years old",
  },
];

// Validation function
const validate = (obj, rules) => {
  const errors = rules.reduce((errs, rule) => {
    const result = rule.test(obj);
    if (result === false) {
      errs.push(rule.message);
    }
    return errs;
  }, []);

  return {
    errors,
    isValid: errors.length === 0,
  };
};

// Testing our object
const result = validate(user, rules);

// {
//   errors:
//    [ 'Password and confirmation do not match',
//      'User must be at least 18 years old' ],
//   isValid: false
// }
```

I hope you enjoyed this exploration of using `Array.reduce` to make our object validations just a bit more consistent and enjoyable.

Happy coding!