Person Age Virtual Property in Mongoose - node.js

I would like to know if there is a simple way in Mongoose of getting a person's age from the associated birthdate in the schema.
// Define the User schema
const Schema = mongoose.Schema;
const UserSchema = new Schema({
id: { type: Number, required: true, unique: true },
first_name: { type: String, required: true, max: [15, 'Too long name'] },
last_name: { type: String, required: true, max: [15, 'Too long surname'] },
gender: { type: String, required: true, enum: ['M', 'F'] },
image: { data: Buffer, contentType: String }
birthdate: { type: Date, required: true }
}, {
collection: 'Users'
});
How to implement this?
// Virtual for user's age
UserSchema
.virtual('age')
.get(function() {
...
});

You can manipulate the date like bellow :
Short answer :
const birthdate = new Date(687882497000);
// replace birthdate by this.birthdate
const nbYearRounded = Math.floor((Date.now() - birthdate.getTime()) / (1000 * 3600 * 24 * 365));
console.log(nbYearRounded);
Exxplaination :
const date = new Date(687882497000);
const timeInMs = date.getTime();
const diffInMs = Date.now() - timeInMs;
const nbDay = diffInMs / 1000 / 3600 / 24;
const nbYear = nbDay / 365;
const nbYearRounded = Math.floor(nbYear);
console.log(date);
console.log(timeInMs);
console.log(diffInMs);
console.log(nbDay);
console.log(nbYear);
console.log(nbYearRounded);
Here is the documentation about VirtualType.prototype.get().
Given example :
var virtual = schema.virtual('fullname');
virtual.get(function () {
return this.name.first + ' ' + this.name.last;
});

This should work
UserSchema.virtual('age').get(function(){
return Math.floor((Date.now() - this.birthdate.getTime()) / (1000 * 3600 * 24 * 365));
});

Related

It says items is undefined

The code is show below.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const user = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
resetToken: String,
resetExpiration: String,
products: [{type: mongoose.Types.ObjectId, required: true, ref: 'Shop'}],
cart: {
items: [
{
productId: {type: mongoose.Types.ObjectId, ref: 'Shop', required: true},
quantity: {type: Number, required: true},
}
]
},
});
user.methods.addToCart = (product) => {
const itemIndex = this.cart.items.findIndex(prod => {
return prod.productId.toString() === product._id.toString();
});
let newQuantity = 1;
const updatedCartItems = [...this.cart.items];
if(itemIndex >= 0) {
newQuantity = this.cart.items[itemIndex].quantity + 1;
updatedCartItems[itemIndex].quantity = newQuantity;
} else {
updatedCartItems.push({
productId: product,
quantity: newQuantity
});
}
const updatedCart = {
items: updatedCartItems
}
this.cart = updatedCart;
return this.save();
}
const model = mongoose.model('User', user);
module.exports = model;
I am trying to store product in the cart instance method as per above schema, but when i send product from my controller to addToCart it says items is undefined on this.cart.items. I haven't used instance method much in mongoose so, i don't know this issue is it with schema or general problem.
let me know if you need any other information.
It was a silly mistake, actually i was using arrow function. so it wasn't bind to schema.

Handle date in the insertion, mongodb

My question is simple how to insert a date in my Schema that will be 1 year from the present date ?
const testSchema = new mongoose.Schema({
User_id: {
type: String,
required:true
},
inscription_date: {
type: Date,
default: Date.now
}
end_inscription_date: {
type: Date,
default: xxxxx // => Date.now + 1 year
}
});
For example:
Submit inscription 2019/07/24, the end date must be 2020/07/24.
You can create a function to calculate the one year later date and use that as your default value.
Try this :
var oneYear = 365 * 24 * 60 * 60 * 1000;
var oneYearLater = function() { return new Date(Date.now() + oneYear);};
Use function oneYearLater in your schema.
const testSchema = new mongoose.Schema({
User_id: {
type: String,
required:true
},
inscription_date: {
type: Date,
default: Date.now
}
end_inscription_date: {
type: Date,
default: oneYearLater// => Date.now + 1 year
}
});
Or simply try to add the milli seconds in Date.now.
end_inscription_date: {
type: Date,
default: Date.now() + 365*24*60*60*1000
}

How to give Char datatype in nodejs

I want to set a char datatype in nodejs model if it is possible. I try to my best for find that solution.
If not possible than please give me another way for doing it.
Thank you
show error
char is not defined
model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const AdminSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: Char,
required: true
},
skype_id: {
type: String
},
password: {
type: String,
required: true
}
});
Use a String type with a maxlength of 1:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const AdminSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
maxlength: 1
},
skype_id: {
type: String
},
password: {
type: String,
required: true
}
});
More info on this can be found in the docs.
Here, some example datatype for you.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const AdminSchema = new Schema({
name: {
type: String, // String Format
required: true // If required
},
first_name: {
type: String // String format, but not required
},
favorite_number: {
type: Number, // Number format
get: v => Math.round( v ),
set: v => Math.round( v ),
alias: 'i'
},
... // etc
});

How to set minimum value great then 0 in mongoose schema?

I think that it was easy question, but I am puzzled.
How Can I add minimum value to mongoose > 0?
var customer = new Schema({
cash: {
type: Number,
minimum: 0
}
});
this code allow 0 value, but I want to do > 0
I know, I can do this
var customer = new Schema({
cash: {
type: Number,
minimum: 0
},
validate: {
validator: function(value) {
return value > 0;
},
message: 'cash need to be > 0'
},
});
*cash is float, and can be very small
But it's too long, Is there an easier way?
You ca specify the min while defining the schema.
var breakfastSchema = new Schema({
eggs: {
type: Number,
min: [6, 'Too few eggs'],
max: 12
},
bacon: {
type: Number,
required: [true, 'Why no bacon?']
},
drink: {
type: String,
enum: ['Coffee', 'Tea'],
required: function() {
return this.bacon > 3;
}
}
});
var Breakfast = db.model('Breakfast', breakfastSchema);
`
var badBreakfast = new Breakfast({
eggs: 2,
bacon: 0,
drink: 'Milk'
});
var error = badBreakfast.validateSync();
assert.equal(error.errors['eggs'].message,
'Too few eggs');
assert.ok(!error.errors['bacon']);
assert.equal(error.errors['drink'].message,
'`Milk` is not a valid enum value for path `drink`.');
badBreakfast.bacon = 5;
badBreakfast.drink = null;
error = badBreakfast.validateSync();
assert.equal(error.errors['drink'].message, 'Path `drink` is required.');
badBreakfast.bacon = null;
error = badBreakfast.validateSync();
assert.equal(error.errors['bacon'].message, 'Why no bacon?');
http://mongoosejs.com/docs/api.html#schema-number-js
Try this:
var customer = new Schema({
cash: {
type: Number,
min: 1
}
});
I assume you are using mongoose.js?

MongoDB Schema - error calling createIndex() for setting expireAt

I wrote my Schema but when I run my Node.js server the following error is showing:
MySchema.createIndex is not a function
I'm using it for setting the expireAt of the record. This is my code:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var config = require('../../config.js');
var tc = new Date();
var te = tc.setSeconds(tc.getSeconds + config.EXPIRE_TOKEN_TIME.ROOM_TOKEN);
var MySchema = new Schema({
name: String,
guide: String,
leader: String,
partecipants_counter : { type: Number, default: 0},
event_counter : { type: Number, default: 0},
createAt: { type: Date, default: tc},
expireAt: { type: Date, default: te},
partecipants: [],
events : [ {
id : Number,
data: String,
user: String
} ]
});
MySchema.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 180 } );
module.exports = mongoose.model(config.DATA_TYPE.ROOM, MySchema);
The syntax should be
MySchema.index( { "expireAt": 1 }, { expireAfterSeconds: 180 } );
More generic example:-
var animalSchema = new Schema({
name: String,
type: String,
tags: { type: [String], index: true } // field level
});
animalSchema.index({ name: 1, type: -1 }); // schema level

Resources