Typeerror: Cannot Read Property 'path' of Undefined Nodejs

Validation

Before we get into the specifics of validation syntax, please keep the following rules in mind:

  • Validation is defined in the SchemaType
  • Validation is middleware. Mongoose registers validation as a pre('save') hook on every schema past default.
  • You can disable automatic validation before save by setting the validateBeforeSave pick
  • You can manually run validation using doc.validate(callback) or doc.validateSync()
  • Yous can manually marker a field every bit invalid (causing validation to neglect) by using doc.invalidate(...)
  • Validators are not run on undefined values. The only exception is the required validator.
  • Validation is asynchronously recursive; when you lot call Model#save, sub-certificate validation is executed likewise. If an error occurs, your Model#relieve callback receives information technology
  • Validation is customizable
                      const            schema =            new            Schema({            name: {            type:            String,            required:            true            } });            const            Cat = db.model('True cat', schema);            // This cat has no name :(            const            cat =            new            True cat(); cat.save(              function(error)            {   assert.equal(error.errors['name'].message,            'Path `name` is required.');    mistake = cat.validateSync();   assert.equal(fault.errors['proper noun'].message,            'Path `proper name` is required.'); });                  

Built-in Validators

Mongoose has several built-in validators.

  • All SchemaTypes accept the born required validator. The required validator uses the SchemaType's checkRequired() function to determine if the value satisfies the required validator.
  • Numbers have min and max validators.
  • Strings have enum, match, minLength, and maxLength validators.

Each of the validator links above provide more information nearly how to enable them and customize their error letters.

                      const            breakfastSchema =            new            Schema({            eggs: {            blazon:            Number,            min: [6,            'Too few eggs'],            max:            12            },            bacon: {            type:            Number,            required: [true,            'Why no bacon?']   },            beverage: {            type:            Cord,            enum: ['Coffee',            'Tea'],            required:                          function()            {            return            this.bacon >            3;     }   } });            const            Breakfast = db.model('Breakfast', breakfastSchema);            const            badBreakfast =            new            Breakfast({            eggs:            2,            bacon:            0,            drink:            'Milk'            });            permit            fault = badBreakfast.validateSync(); affirm.equal(error.errors['eggs'].bulletin,            'Too few eggs'); assert.ok(!fault.errors['bacon']); assert.equal(error.errors['drink'].message,            '`Milk` is non a valid enum value for path `drink`.');  badBreakfast.bacon =            five; badBreakfast.drink =            null;  fault = badBreakfast.validateSync(); assert.equal(error.errors['drink'].message,            'Path `drinkable` is required.');  badBreakfast.salary =            naught; error = badBreakfast.validateSync(); assert.equal(error.errors['salary'].message,            'Why no bacon?');                  

Custom Error Messages

You tin can configure the error message for individual validators in your schema. In that location are two equivalent means to prepare the validator fault message:

  • Array syntax: min: [six, 'Must exist at to the lowest degree 6, got {VALUE}']
  • Object syntax: enum: { values: ['Coffee', 'Tea'], message: '{VALUE} is not supported' }

Mongoose besides supports rudimentary templating for error messages. Mongoose replaces {VALUE} with the value beingness validated.

                      const            breakfastSchema =            new            Schema({            eggs: {            type:            Number,            min: [6,            'Must be at least six, got {VALUE}'],            max:            12            },            drink: {            type:            String,            enum: {            values: ['Coffee',            'Tea'],            message:            '{VALUE} is non supported'            }   } });            const            Breakfast = db.model('Breakfast', breakfastSchema);            const            badBreakfast =            new            Breakfast({            eggs:            2,            drink:            'Milk'            });            const            fault = badBreakfast.validateSync(); assert.equal(error.errors['eggs'].message,            'Must be at to the lowest degree 6, got 2'); assert.equal(error.errors['drink'].bulletin,            'Milk is not supported');                  

The unique Option is Not a Validator

A mutual gotcha for beginners is that the unique selection for schemas is not a validator. It's a convenient helper for edifice MongoDB unique indexes. Meet the FAQ for more information.

                      const            uniqueUsernameSchema =            new            Schema({            username: {            type:            String,            unique:            true            } });            const            U1 = db.model('U1', uniqueUsernameSchema);            const            U2 = db.model('U2', uniqueUsernameSchema);            const            dup = [{            username:            'Val'            }, {            username:            'Val'            }]; U1.create(dup, err => {            // Race condition! This may save successfully, depending on whether            // MongoDB built the alphabetize earlier writing the 2 docs.            });            // You need to look for Mongoose to finish building the `unique`            // index earlier writing. You just need to build indexes one time for            // a given drove, and so yous normally don't need to practise this            // in production. But, if yous driblet the database between tests,            // you will need to use `init()` to await for the alphabetize build to stop.            U2.init().   then(              ()              =>            U2.create(dup)).   catch(              error              =>            {            // Will error, but will *not* be a mongoose validation error, information technology will be            // a duplicate key error.            // See: https://masteringjs.io/tutorials/mongoose/e11000-duplicate-key            affirm.ok(fault);     assert.ok(!error.errors);     affirm.ok(fault.message.indexOf('duplicate key error') !==            -ane);   });                  

Custom Validators

If the congenital-in validators aren't enough, you tin can ascertain custom validators to adapt your needs.

Custom validation is declared by passing a validation office. You can detect detailed instructions on how to do this in the SchemaType#validate() API docs.

                      const            userSchema =            new            Schema({            telephone: {            blazon:            String,            validate: {            validator:                          function(5)            {            return            /\d{iii}-\d{3}-\d{four}/.exam(v);       },            message:                          props              =>            `${props.value}              is not a valid telephone number!`            },            required: [true,            'User phone number required']   } });            const            User = db.model('user', userSchema);            const            user =            new            User();            permit            error;  user.phone =            '555.0123'; error = user.validateSync(); affirm.equal(error.errors['telephone'].message,            '555.0123 is not a valid phone number!');  user.telephone =            ''; error = user.validateSync(); assert.equal(error.errors['phone'].message,            'User phone number required');  user.phone =            '201-555-0123';            // Validation succeeds! Phone number is divers            // and fits `DDD-DDD-DDDD`            mistake = user.validateSync(); affirm.equal(fault,            null);                  

Async Custom Validators

Custom validators can also be asynchronous. If your validator part returns a promise (similar an async function), mongoose will wait for that promise to settle. If the returned promise rejects, or fulfills with the value false, Mongoose will consider that a validation error.

                      const            userSchema =            new            Schema({            name: {            type:            Cord,            // You can also make a validator async by returning a hope.            validate:                          ()              =>            Promise.decline(new            Mistake('Oops!'))   },            email: {            type:            String,            // In that location are two ways for an promise-based async validator to fail:            // one) If the promise rejects, Mongoose assumes the validator failed with the given mistake.            // ii) If the hope resolves to `faux`, Mongoose assumes the validator failed and creates an error with the given `message`.            validate: {            validator:                          ()              =>            Hope.resolve(faux),            message:            'Email validation failed'            }   } });            const            User = db.model('User', userSchema);            const            user =            new            User();  user.email =            'examination@exam.co'; user.proper noun =            'exam'; user.validate().grab(              error              =>            {   assert.ok(error);   affirm.equal(mistake.errors['name'].bulletin,            'Oops!');   assert.equal(mistake.errors['electronic mail'].message,            'E-mail validation failed'); });                  

Validation Errors

Errors returned after failed validation comprise an errors object whose values are ValidatorError objects. Each ValidatorError has kind, path, value, and message properties. A ValidatorError also may have a reason property. If an error was thrown in the validator, this holding will contain the error that was thrown.

                      const            toySchema =            new            Schema({            color:            String,            name:            Cord            });            const            validator =                          function(value)            {            render            /carmine|white|gold/i.test(value); }; toySchema.path('colour').validate(validator,            'Colour `{VALUE}` not valid',            'Invalid color'); toySchema.path('proper noun').validate(              office(v)            {            if            (v !==            'Turbo Man') {            throw            new            Error('Demand to get a Turbo Human being for Christmas');   }            render            true; },            'Name `{VALUE}` is not valid');            const            Toy = db.model('Toy', toySchema);            const            toy =            new            Toy({            colour:            'Green',            name:            'Power Ranger'            });  toy.save(              function(err)            {            // `err` is a ValidationError object            // `err.errors.colour` is a ValidatorError object            affirm.equal(err.errors.color.message,            'Color `Green` non valid');   assert.equal(err.errors.colour.kind,            'Invalid color');   assert.equal(err.errors.color.path,            'color');   assert.equal(err.errors.color.value,            'Green');            // This is new in mongoose 5. If your validator throws an exception,            // mongoose volition use that message. If your validator returns `simulated`,            // mongoose volition utilize the 'Proper name `Power Ranger` is not valid' message.            assert.equal(err.errors.name.message,            'Need to get a Turbo Man for Christmas');   assert.equal(err.errors.name.value,            'Power Ranger');            // If your validator threw an fault, the `reason` property will contain            // the original error thrown, including the original stack trace.            assert.equal(err.errors.name.reason.message,            'Need to go a Turbo Man for Christmas');    assert.equal(err.name,            'ValidationError'); });                  

Cast Errors

Before running validators, Mongoose attempts to coerce values to the correct type. This process is called casting the document. If casting fails for a given path, the error.errors object will comprise a CastError object.

Casting runs before validation, and validation does not run if casting fails. That means your custom validators may presume v is nothing, undefined, or an case of the type specified in your schema.

                      const            vehicleSchema =            new            mongoose.Schema({            numWheels: {            type:            Number,            max:            18            } });            const            Vehicle = db.model('Vehicle', vehicleSchema);            const            medico =            new            Vehicle({            numWheels:            'not a number'            });            const            err = doc.validateSync();  err.errors['numWheels'].name;            // 'CastError'            // 'Cast to Number failed for value "not a number" at path "numWheels"'            err.errors['numWheels'].bulletin;                  

Required Validators On Nested Objects

Defining validators on nested objects in mongoose is tricky, because nested objects are non fully fledged paths.

                      allow            personSchema =            new            Schema({            proper name: {            commencement:            String,            last:            String            } });  affirm.throws(              function()            {            // This throws an error, because 'proper name' isn't a full fledged path            personSchema.path('name').required(true); }, /Cannot.*'required'/);            // To make a nested object required, use a unmarried nested schema            const            nameSchema =            new            Schema({            first:            String,            terminal:            String            });  personSchema =            new            Schema({            proper name: {            type: nameSchema,            required:            true            } });            const            Person = db.model('Person', personSchema);            const            person =            new            Person();            const            fault = person.validateSync(); assert.ok(error.errors['proper name']);                  

Update Validators

In the above examples, you learned well-nigh certificate validation. Mongoose also supports validation for update(), updateOne(), updateMany(), and findOneAndUpdate() operations. Update validators are off by default - y'all need to specify the runValidators selection.

To turn on update validators, fix the runValidators option for update(), updateOne(), updateMany(), or findOneAndUpdate(). Be careful: update validators are off past default considering they have several caveats.

                      const            toySchema =            new            Schema({            color:            String,            proper name:            String            });            const            Toy = db.model('Toys', toySchema);  Toy.schema.path('color').validate(              function(value)            {            render            /crimson|greenish|bluish/i.test(value); },            'Invalid colour');            const            opts = {            runValidators:            true            }; Toy.updateOne({}, {            color:            'non a color'            }, opts,                          role(err)            {   assert.equal(err.errors.color.message,            'Invalid color'); });                  

Update Validators and this

At that place are a couple of key differences between update validators and certificate validators. In the colour validation function below, this refers to the certificate being validated when using document validation. However, when running update validators, the certificate being updated may not be in the server's retention, so by default the value of this is not divers.

                      const            toySchema =            new            Schema({            color:            String,            name:            Cord            });  toySchema.path('colour').validate(              function(value)            {            // When running in `validate()` or `validateSync()`, the            // validator can access the document using `this`.            // Does **not** work with update validators.            if            (this.name.toLowerCase().indexOf('scarlet') !==            -1) {            return            value !==            'red';   }            return            true; });            const            Toy = db.model('ActionFigure', toySchema);            const            toy =            new            Toy({            colour:            'cherry',            name:            'Crimson Power Ranger'            });            const            mistake = toy.validateSync(); assert.ok(error.errors['colour']);            const            update = {            color:            'cerise',            proper name:            'Red Ability Ranger'            };            const            opts = {            runValidators:            true            };  Toy.updateOne({}, update, opts,                          function(fault)            {            // The update validator throws an mistake:            // "TypeError: Cannot read property 'toLowerCase' of undefined",            // because `this` is **non** the certificate being updated when using            // update validators            assert.ok(mistake); });                  

The context option

The context selection lets you prepare the value of this in update validators to the underlying query.

          toySchema.path('color').validate(              function(value)            {            // When running update validators, `this` refers to the query object.            if            (this.getUpdate().$set.name.toLowerCase().indexOf('reddish') !== -1) {            return            value ===            'red';   }            return            truthful; });            const            Toy = db.model('Figure', toySchema);            const            update = {            color:            'bluish',            name:            'Red Power Ranger'            };            // Note the context choice            const            opts = {            runValidators:            true,            context:            'query'            };  Toy.updateOne({}, update, opts,                          function(mistake)            {   affirm.ok(mistake.errors['color']); });                  

Update Validators Only Run On Updated Paths

The other key difference is that update validators only run on the paths specified in the update. For example, in the below example, considering 'name' is not specified in the update operation, update validation will succeed.

When using update validators, required validators but fail when you try to explicitly $unset the key.

                      const            kittenSchema =            new            Schema({            proper name: {            blazon:            String,            required:            true            },            age:            Number            });            const            Kitten = db.model('Kitten', kittenSchema);            const            update = {            color:            'bluish'            };            const            opts = {            runValidators:            true            }; Kitten.updateOne({}, update, opts,                          function()            {            // Operation succeeds despite the fact that 'proper noun' is not specified            });            const            unset = {            $unset: {            proper noun:            one            } }; Kitten.updateOne({}, unset, opts,                          function(err)            {            // Operation fails because 'name' is required            assert.ok(err);   assert.ok(err.errors['name']); });                  

Update Validators Only Run For Some Operations

One final item worth noting: update validators only run on the following update operators:

  • $set
  • $unset
  • $push (>= 4.viii.0)
  • $addToSet (>= 4.8.0)
  • $pull (>= 4.12.0)
  • $pullAll (>= iv.12.0)

For instance, the below update will succeed, regardless of the value of number, because update validators ignore $inc.

As well, $push, $addToSet, $pull, and $pullAll validation does not run whatsoever validation on the assortment itself, but individual elements of the assortment.

                      const            testSchema =            new            Schema({            number: {            type:            Number,            max:            0            },            arr: [{            message: {            type:            String,            maxlength:            10            } }] });            // Update validators won't check this, and so you tin can still `$push button` 2 elements            // onto the array, so long equally they don't have a `message` that's too long.            testSchema.path('arr').validate(              function(v)            {            return            v.length <            2; });            const            Test = db.model('Examination', testSchema);            allow            update = {            $inc: {            number:            1            } };            const            opts = {            runValidators:            truthful            }; Exam.updateOne({}, update, opts,                          part()            {            // There will never exist a validation error here            update = {            $push button: [{            bulletin:            'how-do-you-do'            }, {            message:            'globe'            }] };   Test.updateOne({}, update, opts,                          role(fault)            {            // This will never fault either even though the array will accept at            // least 2 elements.            }); });                  

hamiltontiand1952.blogspot.com

Source: https://mongoosejs.com/docs/validation.html

0 Response to "Typeerror: Cannot Read Property 'path' of Undefined Nodejs"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel