Custom error messages for data types in Ajv

Recently, I delved into using Ajv with ajv-errors to validate JSON schema and generate personalized error messages. While everything is functioning correctly so far, I encountered a challenge in setting custom error messages for individual values based on type.

const emailSchema = {
 type: 'object',
 required: ['foo', 'bar', 'car'],
 properties: {
  foo: { type: 'integer' },
  bar: { type: 'string' },
  car: { type: 'string' }
 },
 errorMessage: {
  type: 'should be an object',
  required: {
  foo: 'foo field is missing',
  bar: 'bar field is missing',
  car: 'car field is missing'
  }
 } 
};

The current output displays the following errors:

[
    {
        "keyword": "type",
        "dataPath": "/foo",
        "schemaPath": "#/properties/foo/type",
        "params": {
            "type": "integer"
        },
        "message": "should be integer"
    },
    {
        "keyword": "errorMessage",
        "dataPath": "",
        "schemaPath": "#/errorMessage",
        "params": {
            "errors": [
                {
                    "keyword": "required",
                    "dataPath": "",
                    "schemaPath": "#/required",
                    "params": {
                        "missingProperty": "bar"
                    },
                    "message": "should have required property 'bar'"
                }
            ]
        },
        "message": "bar field is missing"
    },
    {
        "keyword": "errorMessage",
        "dataPath": "",
        "schemaPath": "#/errorMessage",
        "params": {
            "errors": [
                {
                    "keyword": "required",
                    "dataPath": "",
                    "schemaPath": "#/required",
                    "params": {
                        "missingProperty": "car"
                    },
                    "message": "should have required property 'car'"
                }
            ]
        },
        "message": "car field is missing"
    }
]

In particular, the first error message stating "should be integer" is not specific enough. Is there a way to customize it to something like "foo must be an Integer"? Unfortunately, my attempt was unsuccessful as it resulted in a schema error.

type : {
  foo : "foo must be an Integer"
}

Any insights or solutions would be greatly appreciated!

Answer №1

Make sure to include the keyword errorMessage within each property declaration, as shown in this example:

const emailSchema = {
  type: 'object',
  required: ['foo', 'bar', 'car'],
  properties: {
    foo: {
      type: 'integer',
      errorMessage: {
        // Remember to use errorMessage instead of errorMessages
        type: 'foo must be an Integer', // Your Custom Error Message
      },
    },
    bar: { type: 'string' },
    car: { type: 'string' },
  },
  errorMessages: {
    // Make sure to change from errorMessage to errorMessages
    type: 'should be an object',
    required: {
      foo: 'foo field is missing',
      bar: 'bar field is missing',
      car: 'car field is missing',
    },
  },
}

Answer №2

When faced with scenarios requiring custom errorMessage or other specific data, utilizing the schema path is crucial. Upon encountering a validation error, the error.keyword is provided, prompting the addition of extra validation within if and else blocks, as illustrated below:

schema.allOf= Object.keys(bankCodes).map((key: any) => ({
    if: {
      properties: {
        routingCodeType1: { const: bankCodes[key].code },
      },
    },
    then: {
      properties: {
        routingCodeValue1: {
          pattern: bankCodes[key].pattern, //<-- this was cause of validation fail
          errorMessage: bankCodes[key].errorMessage,
        },
      },
    },
  }))

Consequently, under the error.keyword, details such as pattern and

schemaPath=/#/allOf/2/then/properties/routingCodeValue1/pattern
are obtained.

Henceforth, the utilization of this schema path becomes essential for retrieving pertinent data from the schema. A piece of code that assisted in this process:

const getPatternMessage = (error: any, schema: any) => {
  if (error.keyword === 'pattern') {
    const fieldName = error.dataPath.substring(1); // routingCodeValue1
    const keyArr = error.schemaPath.split('/'); // ['#','allOf','2'..,'pattern']
    keyArr.pop(); // remove '#'
    keyArr.shift(); // remove 'pattern'
    const prop = keyArr.reduce((acc, key) => acc[key], schema);
/** 
prop contains  {
          pattern: '^[a-z]{9}$',
          errorMessage:'routingCodeValue1 should be 9 characters'
        },
*/
    return {
      [fieldName]: prop.errorMessage,
    };
  }
};

This approach facilitates the extraction of custom errorMessage and desired information effectively.

The essence lies in leveraging the schemaPath property for optimal results

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Extracting JSON data from a column in Presto

In my Presto table, there is a specific structure that I am trying to achieve. Specific Date Specific Rates 1/1/2022 {"USD":"725.275","GBP":"29.275000000000002","CAD":"0.713352"} 1/2/202 ...

Uploading video files using XMLHttpRequest encountered an error on a particular Android device

One of our testers encountered an issue where they failed to upload a video file (.mp4) on a specific Android mobile phone. Interestingly, the same file uploaded successfully on an iPhone and another Android device. To investigate further, I attempted to ...

Tips for effectively utilizing innerHTML in this particular scenario

For an assignment, we were tasked with creating a Madlib game where users input words into textfields to replace certain words in a hidden paragraph within the HTML using JavaScript and CSS. The paragraph embedded in the HTML page is as follows: <span ...

Switch off JavaScript beyond the parent element

Struggling with implementing an event to toggle a div using an element located outside of the parent container. I am attempting to achieve the same functionality by targeting elements beyond the parent structure utilizing a span tag. Any assistance on th ...

What are the different ways to interact with the object retrieved from the onloadedmetadata event

Having trouble accessing a specific value in an object that is the result of the onloadedmetadata event. When I log the entire object using audioDuration, I am able to see and retrieve the respective value without any issues. However, when I try to access ...

Issue with $sce.trustAsResourceUrl(url) function in angularJS

Having trouble with loading a file into an iframe. Here is the code for the iframe: <iframe width="100%" height="800px" scrolling="no" ng-src="{{someUrl}}"></iframe> In the controller, I am trying to: $scope.someUrl = $sce.trustAsResourceUr ...

Tips for invoking the ajax pagination feature

Although I have successfully displayed the desired data based on the select box, my pagination feature seems to be malfunctioning. Why is that? The index.php display with broken pagination This snippet shows my ajax script for loading data and setting up ...

Is there a way to effectively incorporate react-native with php and ensure that the data returned by the fetch function is

I'm struggling to make my return value work in this code. Has anyone had success using react-native with php and fetch json? Any tips or advice would be greatly appreciated. PHP $myArray = array(); $myArray['lat'] = $_POST['lat']; ...

Transforming a TypeScript enum into an array of objects

My enum is defined in this structure: export enum GoalProgressMeasurements { Percentage = 1, Numeric_Target = 2, Completed_Tasks = 3, Average_Milestone_Progress = 4, Not_Measured = 5 } However, I want to transform it into an object ar ...

Adjusting the size of icons to fit within a container

I need a div that can display up to 7 icons, depending on certain selections. These icons are from ionicons library. Here is the current code snippet: <div class="item item-text-wrap" style="text-align:center;"> <button class="button" style=" ...

Using axios with async/await to handle unresolved promises in Javascript

I'm facing a challenge with a piece of code I've been working on. Despite my efforts to find a solution online, I haven't had any success so far. Here is the code snippet in question: const fetchSidebarData = async () => { let da ...

Guide to showcasing object characteristics inside an object in Angular2

My USAFacts object contains properties like StateName, as well as objects like State-Bird which hold information about the state bird. If written in JSON, a record of USAFacts would appear as follows: {"StateName": "PA", "State-Bird": [ { "Name": "Ruffed ...

Create a new build for testing and debugging using create-react-app

Currently, I am in the process of developing a web application that utilizes a React frontend and is powered by a golang api layer. Although I do not have extensive experience with Javascript, I find myself struggling with the Node build system. I am loo ...

Determine the number of items in an array with JavaScript in Node

Looking to create a new variable that counts the names in an array and assigns them accordingly? I'm currently stuck on this task. The array contains names: names = [Jan, Jan, Jana] Counting the names is simple, but I'm facing difficulty in org ...

Performing a bulk update using the array provided as the base for the update statement

In my database, there is a table called sched that I frequently need to update. To facilitate this process, I have created an HTML interface that displays the current values of the sched table for users to edit. Upon making changes, scripts are triggered ...

Adjust the appearance of matSelect when the selection menu is activated

What is the best way to adjust mat-select properties when its options are open? <mat-select class="selector"> <mat-option><mat-option> </mat-select> .selector:focus { color: green; } I attempted using focus, but ...

Continue running web AJAX request in Android browser while it is minimized

I need help with my AJAX call var tid = setInterval(mycode, 2000); function mycode() { $.ajax({ url:'/ajx.php', type: "GET", success: function (data) { }, ...

Choose the camera when utilizing the navigate.getUserMedia() function

I am currently utilizing the navigate.getUserMedia() method to record video on my mobile device and perform additional processing on it. However, at the moment, it is only capturing video using the front camera. How can I make it switch to the rear facing ...

Switching classes in jQuery for Internet Explorer 8

I am attempting to update the color of a header when it reaches a certain scroll position. I have implemented this script using jQuery: var $document = jQuery(document), $element = jQuery('#header'), className = 'red'; $docume ...

How to Stop AJAX Requests Mid-Flight with JQuery's .ajax?

Similar Question: Stopping Ajax Requests in JavaScript with jQuery Below is the straightforward piece of code that I am currently using: $("#friend_search").keyup(function() { if($(this).val().length > 0) { obtainFriendlist($(this).va ...