Mastering React Course Form Validation Problem

Hello Everyone,

I am doing Mastering React Course. In the form section, I am facing problem. I cannot use Joi validation with validateProperty property. handleChange for Joi is not giving result properly.

Joi = 17.6.0 ,
React = 18


import { Component } from "react";
import Joi from "joi";
import Input from "./common/input";



class LoginForm extends Component {
  state = {
    account: {
      username: "",
      password: "",
    },
    errors: {},
  };

  schema = Joi.object({
    username: Joi.string().required(),
    password: Joi.string().required(),
  });

  validateProperty = ({ name, value }) => {
    const obj = { [name]: value };
    const schema = { [name]: this.schema[name] };

    const { error } = this.schema.validate(obj, schema);
    return error ? error.details[0].message : null;
  };

  handleChange = ({ currentTarget: input }) => {
    const errors = { ...this.state.errors };
    const errorMessage = this.validateProperty(input);

    if (errorMessage) errors[input.name] = errorMessage;
    else delete errors[input.name];

    const account = { ...this.state.account };
    account[input.name] = input.value;

    this.setState({ account, errors });
  };

  validate = () => {
    const { username, password } = this.state.account;
    const options = { abortEarly: false };
    const { error } = this.schema.validate({ username, password }, options);

    if (!error) return null;

    const errors = {};
    for (let item of error.details) {
      errors[item.path[0]] = item.message;
    }
    return errors;
  };

  handleSubmit = (e) => {
    e.preventDefault();

    const errors = this.validate();
    this.setState({ errors: errors || {} });
    if (errors) return;

    console.log(this.state.account);

    // Call the server
  };

  render() {
    const { account, errors } = this.state;
    return (
      <>
        <form onSubmit={this.handleSubmit}>
          <Input
            name="username"
            label="Username"
            value={account.username}
            onChange={this.handleChange}
            error={errors.username}
          />
          <Input
            name="password"
            label="Password"
            value={account.password}
            onChange={this.handleChange}
            error={errors.password}
          />
          <button type="submit" className="btn btn-primary mt-3">
            Submit
          </button>
        </form>
      </>
    );
  }
}

export default LoginForm;

Please help me why my validateProperty not working.

@Mosh

isn’t there anyone ??? :frowning:

Hi,

Can you also provide the code for the input component ?

@UniqueNospaceShort , yes.

const Input = ({ name, label, value, error, onChange }) => {
  return (
    <div className="form-group">
      <label htmlFor={name}>{label}</label>
      <input
        type="text"
        className="form-control"
        name={name}
        value={value}
        onChange={onChange}
      />
      {error && <div className="alert alert-danger">{error}</div>}
    </div>
  );
};

export default Input;

in joi version 17, you just passing your obj without schema

const {error} = this.schema.validate(obj)

@onlyhasbi , it is not working property. In the username input fields, “Password is required is coming…”. also in the password input fields, “Username cannot be empty is coming.”. In the mosh’s course joi is older version which is deprecated right now i have seen on github.

  1. your trying to set schema dinamically using this way
const schema = { [name]: this.schema[name] };

but in Joi v17 this approach won’t work. to do this, you need to use extract property from joi
read → joi.dev - 17.6.0 API Reference

//change to this one
const rule = schema.extract(name);
const propertySchema = Joi.object({
      [name]: rule
    });
  1. and also validate function in joi v17 only passing one parameter, different from what you see in the mosh tutorial
    read → joi.dev - 17.6.0 API Reference
const { error } = this.schema.validate(obj, schema); //old version
const { error } = this.schema.validate(obj); //new version

check the documentation first when you try update packages to new version

i have done this course but i converted all class component with functional component. if you need some refference. please visit Cinemax - CodeSandbox

1 Like

thank you… @onlyhasbi

you’r welcome @moshfan