The easy and lightweight way to validate data in React Components & Node.js

malkhazidartsmelidze

Malkhazi Dartsmelidze

Posted on May 19, 2020

The easy and lightweight way to validate data in React Components & Node.js

👉 Click here to see new update about this package

Hi, I always wanted to write an article on dev.to and this is my first post about my very first package on npm and of course I'm very excited about it.

First of all I'll introduce you myself. I am full stack software engineer with two year experience writing code using PHP, Laravel, Node.js, React.js, Golang and etc.

Today I want to tell you about my package: max-validator

max-validator is very simple, lightweight (only 2.1kb gzipped), and highly customizable solution to validate javascript object and React.js forms as well.


To install max-validator just run following command in your terminal:

$ npm install --save max-validator

Then use it in your Component or node.js request Handler:

import V from 'max-validate';

const examplePerson = {
  name     : 'John',
  lastname : 'Doe',
  birthdate: '1997-07-17',
  age      : 22,
  email    : 'johndoe@gmail.com',
};

const result = V.validate(examplePerson, {
  name     : 'required|string|min:2|max:30',
  lastname : 'required|string|min:2|max:30',
  birthdate: 'required|date',
  age      : 'required|numeric|min:18|max:100',
  email    : 'required|email|max:50',
});

V.validate() function receives only 2 parameters

  • First parameter must be javascript object containing info to validate
  • Second parameter must be correct scheme which validates above data

Validation scheme contains rules with parameters separated by | symbol.

By default max-validator comes with predefined rules:

  • min {age: 'required|min:18' }
  • max {:height: 'required|max:250' }
  • between {age: 'required|between:18,50' }
  • checked {privacy_policy: 'required|checked' }
  • object {info: 'required|object' }
  • array {points: 'required|array' }
  • boolean {isStudent: 'required|boolean' }
  • alpha_numeric {phoneNumber: 'required|alpha_numeric' }
  • alpha {name: 'required|alpha' }
  • email {email: 'required|email' }
  • alpha_dash {slug: 'required|alpha_dash' }
  • in_array {gender: 'required|in_array:male,female' }
  • not_in {status: 'required|not_in:declined' }
  • json {data: 'required|json' }
  • ip {:ipAdress: 'required|ip' }
  • url {:website: 'required|url' }
  • equals {type: 'required|equals:person' }
  • not_equals {currency: 'required|not_equals:eur' }
  • starts_with {certificate: 'required|starts_with:iso_' }
  • ends_with {email: 'required|ends_with:gmail.com' }
  • date {birthdate: 'required|date' }

And 4 additional rules to validate data:

  • required - Returns error if value is not present or is null or empty
  • nullable - Does not returns error if value is empty, undefined, or null
  • string - Passes value into validator as string
  • numeric - Passes value intro validator as number

Here you can see more about rule and its parameters.


To validate data you have to call validate method like this: V.validate(data, scheme) which returns object containing following fields:

  • hasError - Boolean that represents whether validation failed or not
const result = V.validate(data, scheme);
consol.log(result.hasError); // true or false
  • isError - Function that returns if validation failed for specifig field
const result = V.validate(data, scheme);
consol.log(result.isError('name')); // true or false
consol.log(result.isError('name', 'max')); // true or false (To know validator failed for max length reason)
  • getError - Function that returns first or all error message of specifig field
const result = V.validate(data, scheme);
consol.log(result.getError('name')); // name is required
consol.log(result.getError('name', true)); // name is required, name must contain at least 3 characters

It is very simple to extend max-validator and add your own rule as well.
For example you want to check if given value is array and array length is greater than given param:

import V from 'max-validator';

/**
 * You can add as many params as you want or spread params using spread operator ...params
 * @param {string} RuleName
 * @param {function} ValidatorFunction
 * @param {?string} ErrorMessage
 */
V.extend('custom_array', function(value, min_length){
  const err = { min_length: min_length }

  if(Array.isArray(value) && value.length <= min_length ) {
    return true;
  }

  return err;
}, 'array is invalid, it must have at least :min_length elements');
// You can pass value in message as well

Then you can use rule which was created above:

import V from 'max-validator'

const result = V.validate({data: [1, 2, 3, 4] }, {data:'required|array|custom_array:5'});

console.log(result.hasError, result.isError('data'), result.getError('data'));
// true, true, array is invalid, it must have at least 5 elements

Now you know how to extend validator and handle errors as well, isn't it very simple?


You can also simply override default messages too with setMessages method, where object keys are rule names:

import V from 'max-validate';

V.setMessages({
  required: 'value is required',
  min: 'Minimum value for :name is not met'
  ...
});

V.setDefaultMessage('Something is invalid in your data');

As I said above max-validate is compatible with React.js too.
Here is very simple code to validate user login form:

import React from 'react';
import V from 'max-validate';

const LoginForm = (props) => {
  const [formState, setFormState] = React.useState({
    isValid: false,
    values: {},
    touched: {},
    errors: V.empty(),
  });

  useEffect(() => {
    const result = V.validate(formState.values, {
      email: 'required|email',
      password: 'required|min:6'
    });

    setFormState((formState) => ({...formState,
      isValid: result.hasError,
      errors: result.hasError ? result : V.empty(),
    }));
  }, [formState.values]);

  const handleChange = (event) => {
    event.preventDefault();

    setFormState((formState) => ({ ...formState,
      values: { ...formState.values,
        [event.target.name]: event.target.value,
      },
      touched: {...formState.touched,
        [event.target.name]: true,
      },
    }));
  };

  const hasError =  (field) => (formState.touched[field] && formState.errors.isError(field));

  return (
    <form>
      <input hasError={hasError('email')} name="email" onChange={handleChange} />
      <input hasError={hasError('password')} name="password" onChange={handleChange} />
      <button disabled={!formState.isValid}>Login</button>
    </form>
  );
}

If you want to learn more about max-validator you can look at Github repository and feel free to contribute as well.

Thanks a lot for your interest, I hope you enjoyed it

💖 💪 🙅 🚩
malkhazidartsmelidze
Malkhazi Dartsmelidze

Posted on May 19, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related