skip to Main Content

I am making a chat app with React 18 and Firebase 9.

I use Simple Body Validator for (cleaner) form validation.

In the Register form, I have an input of type file, for uploading the users avatar.

I need to restrict what can be uploaded to JPEG and PNG files only.

For this purpose:

In the Register.jsx component, I have:

import { make, register } from "simple-body-validator";

// Custom validation rule
register('image-only', function (value) {
  let allowedFormats = ["jpg", "jpeg", "png"]; 
  let format = value.name.split('.')[1].toLowerCase();
  return allowedFormats.includes(format);
});

export default function Register() {
  const initialFormData = {
    firstName: "",
    lastName: "",
    email: "",
    avatar: "",
    password: "",
    password_confirmation: ""
  };

  // Apply validation rules
  const validationRules = {
    firstName: ["required", "string", "min:3", "max:255"],
    lastName: ["required", "string", "min:3", "max:255"],
    email: ["required", "email"],
    avatar: ["image-only"],
    password: ["required", "min:6", "confirmed"],
    password_confirmation: ["required"]
  };

  return (
    <FormCard title="Register">
      <form onSubmit={handleSubmit}>
        <div
          className={`mb-2 form-element ${errors.has("avatar") ? "has-error" : null
            }`}
        >
          <label for="avatar" className="form-label">
            Avatar
          </label>
          <input
            type="file"
            id="avatar"
            name="avatar"
            onChange={handleChange}
            className="form-control form-control-sm"
          />
          {errors.has("avatar") ? (
            <p className="invalid-feedback">{errors.first("avatar")}</p>
          ) : null}
        </div>

      </form>
    </FormCard>
  );
}

The problem

Although the disallowed formats are excluded, as expected, there is no validation error message and I don’t know how to add it.

Question

How do I add a message to the custom validation rule I have created?

2

Answers


  1. Chosen as BEST ANSWER

    This is what worked for me:

    register('image-only', function (value) {
      let allowedFormats = ["jpg", "jpeg", "png"];
      let format = value.name.split('.')[1].toLowerCase();
      return allowedFormats.includes(format);
    }, function() {
      return "Only JPG, JPEG, and PNG files are allowed.";
    });
    

  2. In your custom validation rule ‘image-only’, you’re returning just a boolean to indicate if the validation passed or failed. To add a custom message, you need to return an object that includes both whether the rule passed and what the error message should be if it didn’t.

    Here’s how you can tweak your image-only rule:

    register('image-only', function (value) {
      let allowedFormats = ["jpg", "jpeg", "png"];
      let format = value.name.split('.')[1].toLowerCase();
      let isValid = allowedFormats.includes(format);
      
      return {
        passed: isValid,
        message: isValid ? "" : "Hold up! Only JPG, JPEG, and PNG files are allowed."
      };
    });
    
    

    Your handleSubmit function should be the one looking at these validation results and setting the state accordingly. Like, if validation fails, you should update your component’s state so that you can show the error messages.

    function handleSubmit(event) {
      event.preventDefault();
      
      // Validate that form!
      const errors = make(validationRules, initialFormData);
      
      // Update your state with any errors
      setErrors(errors);
      
      // If we're all good, go ahead and submit the form
      if (Object.keys(errors).length === 0) {
        // Proceed with whatever your form is supposed to do
      }
    }
    

    Finally, rendering. You’ve got a piece of JSX code that checks if there’s an error for the "avatar" field and displays it. Just make sure this part is working as expected.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search