Partial and complete validation of the form with Joi on React
Tags: react, joi, javascript, frontend
Published: 2021-02-27 09:10:00

---
title: Partial and complete validation of the form with Joi on React
published: true
description: The partial one when I’m typing, while the full validation when I click on the submit button
tags: react, joi, javascript, frontend
//cover_image: https://direct_url_to_image.jpg
---

Recently I started using [Joi](https://github.com/sideway/joi)  to validate forms on my React application.

In this code snippet I’ll show you how to do a partial and a full validation
The partial one when I’m typing, while the full validation when I click on the submit button.

Below here the syntax of the schema:
```js
import Joi from 'joi';
import parsePhoneNumber from 'libphonenumber-js';

export default Joi.object().keys({
    'name': Joi.object({
        'text': Joi.string().required(),
        'voice': Joi.string().allow("")
    }).required(),
    'surname': Joi.object({
        'text': Joi.string().required(),
        'voice': Joi.string().allow("")
    }).required(),
    'phoneNumber': Joi.string().custom((phoneNumber, helper) => {
        const res = parsePhoneNumber(phoneNumber, 'IT');
        if (res !=== undefined && res.isValid()){
            return phoneNumber;
        }
        return helper.error('phoneNumber.invalid');
    }).required()
});
```
Now I necessarily split the schema into more parts because I had to export different models from the file.
To make it more readable, the code becomes like this:
```js
import Joi from 'joi';
import parsePhoneNumber from 'libphonenumber-js';

const isValidPhoneNumber = (phoneNumber, helper) => {
    const res = parsePhoneNumber(phoneNumber, 'IT');
    if (res !== undefined && res.isValid()){
        return phoneNumber;
    }
    return helper.error('phoneNumber.invalid');
};

const voiceSchema = Joi.object({
    'text': Joi.string().required(),
    'voice': Joi.string().allow("")
});

export const phoneNumberSchema = Joi.string().custom(isValidPhoneNumber).required();
export const nameSchema = voiceSchema.required();
export const surnameSchema = voiceSchema.required();

export default Joi.object().keys({
    'name': nameSchema,
    'surname': surnameSchema,
    'phoneNumber':phoneNumberSchema
});
```
In the frontend it will look like this:
```js
import React, { useState } from 'react';
import schema, { phoneNumberSchema, nameSchema, surnameSchema } from './schema2';

export const MyComponent = () => {

    const [ errors, setErrors ] = useState([]);

    function validationField(schema, value, field) {
        const err = JSON.parse(JSON.stringify(errors));
        const res = schema.validate(value);
        let errorsList = {};
        if (res.error) {
            res.error.details.forEach((error) => {
                errorsList[field] = error.message;
            });
            setErrors({
                ...errors,
                ...errorsList
            });
        } else {
            delete err[field];
            setErrors(err);
        }
    }

    function validationPaylod(payload) {
        const res = schema.validate(payload);
        if (res.error){
            // ko!
        } else {
            // ok!
        }
    }

    function handleChange(field, text, voice) {
        const payload = { 
            text,
            voice
        };
        switch (field) {
            case 'name':
                validationField(nameSchema, payload, 'name');
                break;
            case 'surname':
                validationField(surnameSchema, payload, 'surname');
                break;
            case 'phoneNumber':
                validationField(phoneNumberSchema, text, 'phoneNumber');
                break;
        }
    }

    return (<>{/* RENDER INSIDE HERE !!!! */}</>)
};
```

In this case the **handleChange** function (with the three required parameters) will be called at the onChange event of the form and at the end we will call the **validationPayload** function.

Into my **Errors** state I have an object with all errors divided for keys.

Enjoy mates!