3

I have set up Mongoose custom validation with errors and would like to display these error messages in React. I am unfortunately unable to retrieve the error messages. I have tried looking for solutions, but am unfortunately still having trouble.

My code is as follows:

Server-side:

- dataModel.js

const mongoose = require("mongoose");
const uniqueValidator = require("mongoose-unique-validator");
const moment = require("moment");

const dataSchema = mongoose.Schema(
  {
    name: {
      type: String,
      required: [true, "Name is required."],
      validate: {
        validator: function (name) {
          return /^[a-zA-Z]+$/.test(name);
        },
        message: "Only alphabetic characters allowed.",
      },
    },
    surname: {
      type: String,
      required: [true, "Surname is required."],
      validate: {
        validator: function (surname) {
          return /^[a-zA-Z]+$/.test(surname);
        },
        message: "Only alphabetic characters allowed.",
      },
    },
    idNumber: {
      type: String,
      required: [true, "ID Number is required."],
      unique: true,
      validate: [
        {
          validator: function (idNumber) {
            return idNumber.toString().length === 13;
          },
          message: (idNumber) =>
            `ID Number Must Have 13 Numbers. You entered ${
              idNumber.value
            }, which is ${idNumber.value.toString().length} numbers long.`,
        },
        {
          validator: function (idNumber) {
            return !isNaN(parseFloat(idNumber)) && isFinite(idNumber);
          },
          message: (idNumber) =>
            `ID Number Can Only Contain Number Values. You entered ${idNumber.value}.`,
        },
      ],
    },
    dateOfBirth: {
      type: String,
      required: [true, "Date of Birth is required."],
      validate: {
        validator: function (dateOfBirth) {
          return moment(dateOfBirth, "DD/MM/YYYY", true).isValid();
        },
        message: "Invalid Date of Birth Format. Expected DD/MM/YYYY.",
      },
    },
  },
  {
    timestamps: true,
  }
);

dataSchema.plugin(uniqueValidator, { message: "ID Number Already Exists." });

module.exports = mongoose.model("Data", dataSchema);

- dataController.js

exports.addController = async (req, res) => {
  const { firstName, surname, idNumber, dateOfBirth } = req.body;

  const newData = new Data({
    name: firstName,
    surname,
    idNumber,
    dateOfBirth,
  });

  try {
    await newData.save();
    res.send({ message: "Data Added Successfully" });
  } catch (error) {
    if (error.name === "ValidationError") {
      let errors = {};

      Object.keys(error.errors).forEach((key) => {
        errors[key] = error.errors[key].message;
      });
      
      console.log(errors)

      return res.status(400).send(errors);
    }
    res.status(500).send("Something went wrong");
  }
};

Output - console.log:

Screenshot - Console - Back

Client-side:

- dataForm.js

  const addData = async () => {
    try {
      axios({
        url: "/data/add",
        method: "post",
        data: {
          firstName,
          surname,
          idNumber,
          dateOfBirth,
        },
        headers: {
          "Content-type": "application/json",
        },
      }).then(function (response) {
        alert(response.data.message);
        console.log(response.data.message);
      });
    } catch (error) {
      console.log(error);
      }
  };

Output - Console:

Screenshot - Console

Output - Postman (Initial):

{
  "message": [
    "Only alphabetic characters allowed.",
    "ID Number Can Only Contain Number Values. You entered 888888888888a."
  ],
  "error": {
    "errors": {
      "surname": {
        "name": "ValidatorError",
        "message": "Only alphabetic characters allowed.",
        "properties": {
          "message": "Only alphabetic characters allowed.",
          "type": "user defined",
          "path": "surname",
          "value": "Bösiger"
        },
        "kind": "user defined",
        "path": "surname",
        "value": "Bösiger"
      },
      "idNumber": {
        "name": "ValidatorError",
        "message": "ID Number Can Only Contain Number Values. You entered 888888888888a.",
        "properties": {
          "message": "ID Number Can Only Contain Number Values. You entered 888888888888a.",
          "type": "user defined",
          "path": "idNumber",
          "value": "888888888888a"
        },
        "kind": "user defined",
        "path": "idNumber",
        "value": "888888888888a"
      }
    },
    "_message": "Data validation failed",
    "name": "ValidationError",
    "message": "Data validation failed: surname: Only alphabetic characters allowed., idNumber: ID Number Can Only Contain Number Values. You entered 888888888888a."
  }
}

Output - Postman (Current):

Screenshot - Postman

I would appreciate any help that anyone is willing to offer.

5
  • try with console.log(error.response); in your axios req Commented Jan 29, 2022 at 22:15
  • 1
    stackoverflow.com/questions/49967779/axios-handling-errors/… Commented Jan 29, 2022 at 22:17
  • Hi @cmgchess. Thank you for your messages. I have tried logging all of the following with no success: console.log(error); console.log(error.response); console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); console.log(error.request); console.log('Error', error.message); Commented Jan 30, 2022 at 6:10
  • what did it show on console Commented Jan 30, 2022 at 6:37
  • @cmgchess None of the console.log()s provided any output except for the normal: (POST localhost:3000/data/add 400 (Bad Request)) and (bundle.js:2068 Uncaught (in promise) Error: Request failed with status code 400 at createError (bundle.js:2068:15) at settle (bundle.js:2335:12) at XMLHttpRequest.onloadend (bundle.js:1395:7)). Commented Jan 30, 2022 at 7:19

1 Answer 1

1

I have managed to sort the problem out and return and display the Mongoose validation errors on the React frontend.

I amended the React post method as follows:

const addData = async () => {
    try {
      let response = await axios({
        url: "http://localhost:8080/data/add",
        method: "post",
        data: {
          firstName,
          surname,
          idNumber,
          dateOfBirth,
        },
        headers: {
          "Content-type": "application/json",
        },
      })
      .then((response) => {
        alert(response.data.message);
      })
      .then(() => {
        window.location.reload();
      });
      alert(response.data.message);
    } catch (error) {
      alert(Object.values(error.response.data) + ".");
    }
  };

I had to format the method as the error code was not being reached and had to return and display the data using Object.values() as the responses were objects.

Thank you @cmgchess for pointing me in the right direction.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.