javascriptjsonschemaajv

How do I validate a string using a regular expression with Ajv?


I'm trying to validate a string(Phone number) with this regex ^+[0-9]{9,12}$

but I get this error ... .pattern should match format "regex" ...

I've been through the documentation at https://ajv.js.org etc. looked at examples etc. and tried a lot of variations, but can't seem to figure out what is wrong with my code.

Here is my code:

const schema = {
    type: 'object',
    properties: {
        users: {
            type: 'array',
            items: {
                type: 'object',
                properties: {
                    userReference: { type: 'string' },
                    phone: {
                        type: 'string'
                        , pattern: "^\+[0-9]{9,12}$" // If I remove this line, the model is seen as valid (and no errors)
                    }
                }
            }
        }
    },
    required: ['users'],
    errorMessage: { _: "One or more of the fields in the 'legacy' data path are incorrect." }
};

const schemaSample = {
    "users": [
        {
            "phone": "+25512345678", // should be valid
            "userReference": "AAA"
        },
        {
            "phone": "+5255 abc 12345678", // should be invalid
            "userReference": "BBB"
        }
    ]
};

var ajv = Ajv();
ajv.addSchema(schema, 'schema');

var valid = ajv.validate('schema', schemaSample);
if (valid) {
    console.log('Model is valid!');
} else {
    console.log('Model is invalid!');
}

Link to JSFiddle: http://jsfiddle.net/xnw2b9zL/4/ (Open Console / Debugger to see the full error)


Solution

  • TL; DR

    Your regular expression is valid in a literal notation form but not in a constructor form where it is embedded into a string.

    "\+""\\+"

    When embedding a regular expression into a string, double check your escape characters!

    Why?

    Because useless escape characters will be ignored. If it wasn't for constructing a regular expression you have no reason to escape a '+' character:

    "\+" === "+"
    //=> true
    

    The error you saw had nothing to do with the data, it was in the construction of the schema. As you can see here:

    const ajv = new Ajv;
    
    try {
      ajv.compile({type: 'string' , pattern: '^\+[0-9]{9,12}$'});
    } catch (e) {
      console.log(`ERR! ${e.message}`);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.12.2/ajv.min.js"></script>

    But digging deeper, it has nothing to do with Ajv either. Ajv does mention:

    Ajv uses new RegExp(value) to create the regular expression that will be used to test data.

    See https://ajv.js.org/keywords.html#pattern

    So what does it mean to do new RegExp("\+")? Let's find out:

    // similar error because "\+" and "+" are the same string
    try { new RegExp("\+") } catch (e) { console.log(e.message) }
    try { new RegExp("+") } catch (e) { console.log(e.message) }

    Related