How to pass schema type: Object's key rules - javascript

I am trying to understand how to validate, an object using Meteor-Collection2. I can better explain in the code below:
// This is the object structure to validate
// const obj = {
// name: 'Test',
// active: true,
// }
Test.schemaObj = {
someOtherName: {
type: String, // Not the same as obj variable
},
testType: {
type: Object,
// The goal is to define rules for validation for
// things that this will contain.
},
// Inside the object: {
// type: String,
// required: true,
//},
// Inside the object: {
// type: Boolean,
// required: true,
//},
};
I understand that required is automatically set to true when not defined.
My purpose is to basically list all the keys that the object must have and their validation rules. I know how an array of object works, I am just not sure what the syntax is for object validation.
I went through the documentation and stack-overflow, but I was not able to find it anywhere online explicitly showing the syntax.
I am sure that I am missing something basic however, being new to this I was hoping that someone can help me.

I understood which you want to validate the testType object. Then there are two ways:
You can add the blackbox: true, this will allow that object have any structure;
You need to define each property of object, like this:
Test.schemaObj = {
someOtherName: {
type: String, // Not the same as obj variable
},
testType: {
type: Object,
// The goal is to define rules for validation for
// things that this will contain.
},
"testType.attribute1": {
type: String,
required: true,
},
"testType.attribute2": {
type: Boolean,
required: true,
},
};

Related

nodejs objects property can only be changed to int and not string

i just got this wierd issue in which the code below returns the refno for all Object in the array as expected But
let records = await Expense.find({}).exec(); // records is an array of objects [{},{}]
for (let obj of records) { // the obj has a refno property which i want to change
obj.refno = 0 // this works as expected by changing refno property to 0
}
console.log(records)
this code of code below of chaning the properties value to string Does not work
for (let obj of records) {
obj.refno = "QM"+obj.refno
}
console.log(records) // IN this the refno. doesnt change
my requirment is to change the refno to a string
//the object
{
_id: 5efed2c813b03d331e4dc052,
refno: 102,
project: 'EV Battery Pack',
invoiceno: 'dia',
description: 'black frame',
date: '2020-07-03',
}
so chaning the property to other number works but not to string , i cant get how this happens or am i missing something ?, anyways i got around this by declaring another property and storing the string in it but I dont know why the int cant be changed to string inside object
can some one explain why this happens
thanks for help
Edit : schema of expense
var schema = new Schema({
refno: { type: Number, require: true },
project: { type: String, require: true },
projectid: { type: Number, require: true },
invoiceno: { type: String, require: true },
description: { type: String, require: true },
date: { type: String, require: true },
INR: { type: Number, require: true },
USD: { type: Number, require: true },
remarks: { type: String, require: true },
});
The result of your .find().exec() call are mongoose documents which do not allow to modify their values if the resulting datatype is not compliant with the schema-constraints.
However, you can use .lean() (see https://mongoosejs.com/docs/api.html#query_Query-lean) on the mongoose document which will convert it to a plain js-object which you then can modify arbitrarily:
let records = await Expense.find({}).exec().lean();

Is it possible to have at least one property required in Mongoose?

I have created a Schema model in Mongoose, which has several properties, including the following shown below.
The problem with all this is that the properties: name, description and countries, ONLY ONE of them, should be required, and not all three of them.
That is to say, if I make a PUT of this model, and I don't put any property, the model is NOT valid, but, if I put one of them, the model is (or if I put two, or even three of them).
However, the required here is not valid, since it implies to add three properties.
I've tried with required, validate or Mongoose's own hooks, but none of it has worked.
const example = new Schema({
name: {
type: String,
required: true,
unique: true
},
description: String,
countries: {
type: [
{
type: String,
}
],
},
email: {
type: String
},
sex: {
type: String
},
});
I hope that with the required, I will always require the three properties
You can use custom function as the value of the required property.
const example = new Schema({
name: {
type: String,
required: function() {
return !this.description || !this.countries
},
unique: true
},
description: String,
countries: {
type: [
{
type: String,
}
],
},
email: {
type: String
},
sex: {
type: String
},
});
I doubt that there is a built-in way to achieve this specific type of validation. Here's how you could achieve what you want using the validate method:
const example = new Schema({
name: {
type: String,
unique: true,
validate() {
return this.name || this.countries && this.countries.length > 0 || this.description
}
},
description: {
type: String,
validate() {
return this.name || this.countries && this.countries.length > 0 || this.description
}
},
countries: {
type: [String],
validate() {
return this.name || this.countries && this.countries.length > 0 || this.description
}
}
});
It will be called for all three fields in your schema, and as long as at least one of them is not null, they will all be valid. If all three are missing, then all three will be invalid. You can also tune this to fit some more specific needs of yours.
Note that this works because the context (the value of this) of the validate method refers to the model instance.
Edit: better yet, use the required method, which basically works in the same way, as pointed out in the other answer.

Check for not required property existing in mongoose model variable

So, I have this mongoose scheemas structure:
const execStatusScheema = new mongoose.Schema(...)
const notifyScheema = new mongoose.Schema({
...
sms: {
type: Boolean,
required: true
},
smsStatus: {
type: execStatusScheema
},
telegram: {
type: Boolean,
required: true
},
telegramStatus: {
type: execStatusScheema
},
voice: {
type: Boolean,
required: true
},
voiceStatus: {
type: execStatusScheema
}
})
const Notify = mongoose.model('Notify', notifyScheema)
module.exports.Notify = Notify
as you can see in Notify scheema smsStatus, voiceStatus and telegramStatus are not required. If sms is false, the smsStatus property is not assiged in my code, and for voice and telegram the same behavior. I want to check in Notify some of these propertys. I do the follow:
const uncomplitedNotifies = await Notify.find(...).select('smsStatus voiceStatus telegramStatus sms voice telegram')
uncomplitedNotifies.forEach(async notify => {
console.log(notify)
if ('telegramStatus' in notify) {
console.log('123')
}
...
Result is:
{ _id: 5ba07aaa1f9dbf732d6cbcdb,
priority: 5,
sms: true,
telegram: false,
voice: false,
smsStatus:
{ status: 'run',
_id: 5ba07aaa1f9dbf732d6cbcdc,
errMessage: 'Authentication failed',
statusDate: '2018-9-18 12:10:19' } }
123
Ok, I find one, and its ok, but my if statment is true even I have no this property in my object. I guess it check in scheema object, where its declared, but I want to check in my 'real' object I got by query.
I also try this checking case, but the same result:
if (typeof something === "undefined") {
alert("something is undefined");
}
How can I check this object correctly ?
The in operator checks the object's own properties and its prototype chain. The unset properties are in the prototype chain of your object, but not on the object's own properties:
const hasTelegramStatus = 'telegramStatus' in document; // true
const hasTelegramStatus = document.hasOwnProperty('telegramStatus') // false
One option is to convert the query into an object by doing document.toObject(), which will remove the prototype chain and only return the own properties.

Javascript RegEx Nested Object Key

I have a preset object which has bunch of keys like this:
preset: {
abc: { type: Boolean, optional: true},
bcd: { type: Boolean, optional: true},
def: { type: Boolean, optional: true},
efg: { type: Boolean, optional: true},
}
I tried using regex like this:
regEx: {
test: /abc|bcd|def|efg/,
}
Now I want to use it to test the keys of preset.
I tried to many different ways but eslint keeps giving me syntax error:
preset.[regEx.test]: { type: Boolean, optional: true}
[`preset.${regEx.test}`]: { type: Boolean, optional: true}
etc.
This is for db schema, if I don't use regEx, it's going to be super long to check. Can someone help?
You can't check property's names by trying to access them by regexp object. You need to iterate over object property's and check their name.
for( var i in preset ) if( preset.hasOwnProperty( i ) ) {
if( regEx.test.test( i ) ){
var item = preset[i]
//this is valid property name
if( item.type === Boolean && item.optional === true ){
// some other checks
} else {
//not boolean or not optional
}
} else {
//this is not valid property name
}
}

Replacing object's name inside another object

I have an object which serves as parameter that I pass on to the jquery validator plugin:
var param = {rules: {
name: {
required: true
},
tel: {
required: true,
number: true
}
}
};
I have three forms which have have similar fields, yet they are named like 'xxx[name]','xxx[tel]', etc. I need to write a function that would replace the name of the object inside the param object, but for some reason i'm confused as to how I can do that. I've tried:
function insertParam(par1) {
var param = {rules: {
name: {
required: true
},
tel: {
required: true,
number: true
}
}
};
param['rules']['name'] = param['rules'][par1 + '[name]'];
param['rules']['tel'] = param['rules'][par1 + '[tel]'];
return param;
};
But this doesn't work. So, how is this done properly? Will appreciate any feedback.
EDIT: Fiddle http://jsfiddle.net/qzgaS/
You mixed assignment order and notations.
Since you are using some 'special' (e.g, [) characters in your property names, you should use the bracket notation.
Otherwise, for constant properties, use
foo.bar
instead of
foo['bar']
for better readability.
You wanted to generate a parameter object from a template. This can be done by constructing an object with the desired properties and assigning the template's values to them, as such:
function insertParam(par1) {
var rules = {
name: {
required: true
},
tel: {
required: true,
number: true
}
};
var result = {"rules":{}};
result.rules[par1 + '[name]'] = rules.name;
result.rules[par1 + '[tel]'] = rules.tel;
return result;
};
When called it will produce the desired output:
>>> insertParam('Call')
{
"rules": {
"Call[name]": {
"required": true
},
"Call[tel]": {
"required": true,
"number": true
}
}
}
Demo

Categories

Resources