Mongoose getter is getting undefined parameter - javascript

I'm storing a price value in my Mongoose schema according to the answer from how should i store a price in mongoose?
I have the following code in my schema definition:
price: {
value: {
type: Number,
get: getPrice,
set: setPrice,
min: 0
},
currency: {
type: String,
default: 'PLN',
trim: true,
enum: ['PLN', 'EUR']
}
},
and my get function:
function getPrice(num){
return (num/100).toFixed(2);
}
However, whenever this getter function is called I can see that the num parameter in undefined.
Do you know what might be the reason for that? And how could I fix this?

Add a default of zero for value. Also, mongoose is notoriously bad about subdocuments that are not inside an array, which may be causing this problem.
value: {
type: Number,
get: getPrice,
set: setPrice,
min: 0,
default: 0
},

If getter/setters give you problems with mongoose models, use the native static methods in mongoose schemas:
mySchema.static('getPrice', function(){
//'this' in the context means a document that shares the schema
return (this.price.value/100).toString(2);
});
You can invoke the method in any document that have said schema:
var myPrice = oneMongooseDocument.getPrice();
Is a very clean approach.

Related

Mongoose findOne sending null

I am trying to edit a discord bot made in python (I stored data initially in python) and transferring it to javascript (node.js) and can't feature out while connecting to my old db why findOne giving me null while providing proper discord id.
Without anything inside
Code
anifarm.findOne();
Output
{
_id: 707876147324518400,
farmed: 17,
ordered: 5,
pimage: 'https://media.tenor.com/images/e830217a5d9926788ef25119955edc7f/tenor.gif',
pstatus: 'I want you to be happy. I want you to laugh a lot. I don’t know what exactly I’ll be able to do for you, but I’ll always be by your side.',
avg: 184,
speed: 2,
badges: [
'https://cdn.discordapp.com/attachments/856137319149207563/856137435696332800/Black-and-Yellow-Gaming-Badge--unscreen.gif',
'https://cdn.discordapp.com/attachments/856137319149207563/862219383866523688/Front-removebg-preview.png', 'https://cdn.discordapp.com/attachments/856137319149207563/862240758768599100/download-removebg-preview.png'
],
setBadges: 'https://cdn.discordapp.com/attachments/856137319149207563/862240758768599100/download-removebg-preview.png'
}
With id inside
Code
anifarm.findOne({
_id: 707876147324518400
});
Output
null
anifarm in the schema.
Decleared Schema
module.exports = mongoose.model('anifarm', new mongoose.Schema({
_id: Number,
farmed: {
type: Number,
default: 0
},
ordered: {
type: Number,
default: 0
},
pimage: {
type: String,
default: ""
},
pstatus: {
type: String,
default: ""
},
avg: {
type: Number,
default: 200
},
speed: {
type: Number,
default: 2
},
badges: {
type: Array,
default: []
},
setBadges: {
type: String,
default: ""
}
},
{
collection: 'anifarm',
versionKey: false
})
);
I cannot figure out what am I doing wrong. This problem also happens with .find()
Nothing inside find fetches everything by if I provide id it sends a empty array.
A Little help would be appreciated
For you problem use mongoose-long that should fix your problem.
This library will handle all long type data for mongoose since mongoose cannot handle long type data
you can't pass an id as a number, you will have to use ObjectId to convert the id to an instanceof ObjectId
Change your code like this
anifarm.findOne({
_id: mongoose.Types.ObjectId(707876147324518400);
});
If you're querying by _id, use findById() instead.
anifarm.findById("707876147324518400")
Official docs here

Mongoose: value not incrementing through $inc

I have been struggling with this issue for days. For some unknown reason, a specific field ("reviewCounts") is not incrementing no matter what alternative methods I try.
Here is my Schema
let itemSchema = new mongoose.Schema({
rank: Number,
image: String,
name: String,
title: String,
count: Number,
category: String,
ratings: Object,
reviewCounts: Number,
reviews: Array,
tags: Object,
})
and this is the update method:
Item.findOneAndUpdate({name: item,title:title}, {
$inc:{"reviewCounts":1},
$set:averageQuery,
$inc:query
},{strict:false},
function (err, data) {
}
}
$inc works completely find on "query" not it does not increment "reviewCounts". I have tried using $set to manually set the value, but that did not work too. I doubled-checked and confirmed that the field is int32 as intended. What could be the reason behind this issue?
When you build your update statement this way:
{
$inc:{"reviewCounts":1},
$set:averageQuery,
$inc:query
}
you're duplicating the $inc key in your JavaScript object. JavaScript interprets such code as:
{
$set:averageQuery,
$inc:query
}
so simply last usage of particular key "wins" thus you loose the reviewCounts part.
You need to make sure that there's only one $inc and you can use the spread operator to combine your $inc's:
$inc:{ ...query, "reviewCounts":1 }

Mongoose: how to prevent null values being added to array of ObjectId

Title says it all. Below is a schema property definition that I thought would work, but doesn't do the job. I figured required: true on the type object should work?
users: {
type: [
{
type: Schema.Types.ObjectId,
ref: 'User',
required: true
}
],
default: []
}
the following query allows a null value to be added to the array:
MyModel.findByIdAndUpdate(id, {$addToSet: {users: ['']}})
aaaaaaaand, of course as soon as I post to SO, i find the answer for myself. need to set option runValidators: true on update...
This is the real reason I post to SO, its like always carrying an umbrella, its guaranteed not to rain.

Why new documents in mongo have an object and not an ObjectId?

When inserting new documents in mongodb, ids don't look like ObjectId and instead they look like an object.
"_id" : {
"_bsontype" : "ObjectID",
"id" : "U\u0013[-Ф~\u001d$©t",
"generationTime" : 1.43439e+09
}
Expected type:
"_id" : ObjectId("55107edd8e21f20000fd79a6")
My mongodb version is 3.0.3 and this is pretty much the code and the schema
var Script = {
run: function() {
return CourseModel.findQ()
.then(function(courses){
return courses.map(worker);
}).catch(function(error){
console.log(error);
});
}
};
function worker(course){
var category = { name: course.name, displayOrder: 0 };
return CategoryModel.createQ(category).then(function() {
course.set('name', undefined);
return course.saveQ();
});
}
module.exports = Script;
var CategorySchema = new Schema({
name: {
type: String,
required: true,
unique: true
},
active: {
type: Boolean,
default: true
},
displayOrder: Number,
updateDate: Date,
subcategories: [{
type: Schema.Types.ObjectId,
ref: 'subcategories'
}]
});
That is what an ObjectID is. It is simply an object that contains those properties.
http://docs.mongodb.org/manual/reference/object-id/
ObjectId is a 12-byte BSON type, constructed using:
a 4-byte value representing the seconds since the Unix epoch,
a 3-byte machine identifier,
a 2-byte process id, and
a 3-byte counter, starting with a random value.
{
"_bsontype" : "ObjectID",
"id" : "U\u0013[-Ф~\u001d$©t",
"generationTime" : 1.43439e+09
}
U\u0013[-Ф~\u001d$©t is the 12 character binary string which gets converted to the familiar 24 char hex string (55107edd8e21f20000fd79a6) when the object as a whole is represented as a text value (i.e. its .toString function is invoked)
In Mongoose the documents also have a .id getter which give you the 24 char hex as a string value.
The malformed ObjectIds are caused by a conflict with the mongoose version that mongoose-q is using. You'll need to update to mongoose-q to version 0.1.0. I was using 0.0.17 previously and saw exactly the same behavior that you saw here.
I was having the same issue here: ObjectID not storing hexadecimal value
It's definitely an issue with environments and something strange with the brew installation of MongoDB. I found that uninstalling from brew and reinstalling manually solved my issue. http://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x/
While I didn't figure out from a code/technical standpoint why it is returning the 12-byt BSON ObjectID rather than the Hexadecimal ObjectID... uninstalling MongoDB from brew and reinstalling it manually solved the issue.

Mongoose doesn't create TTL indexes

This is my Mongoose model:
var sessionSchema = new Schema({
_id: { type: String, required: true, index: { unique: true } },
user: { type: Schema.Types.ObjectId },
expire: { type: Date, index: { expireAfterSeconds: 21600 } }
})
module.exports = mongoose.model('Session', sessionSchema)
I need to be able to set a date object into expire (usually it's something like Date.now plus a few minutes) and have the object removed from the collection after 6 hours past the expiration.
However, I'm not able to have Mongoose to create the index. When I run db.sessions.getIndexes() in the mongo console, here's the output:
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "dev.sessions"
}
]
I've tried also with different syntaxes, like
expire: { type: Date, expires: 21600 } (Mongoose's short-hand version).
I tried also defining the index at the schema level:
sessionSchema.index({ expire: 1 }, { expireAfterSeconds: 21600 })
None is working.
Unlike others who asked questions on SO, my index is simply not created. I've tried also removing the collection and the database as well, and when they're recreated they still don't contain the index.
Versions: Mongoose 3.8.19, MongoDB 2.6.5 (OSX) and Node.js 0.10.33
Edit
More info: I tried creating the index directly from the mongo console, with:
db.sessions.ensureIndex({"expire":1}, {expireAfterSeconds: 21600})
That appears to be working (the index is created).
However, it's not working with Mongoose in any way.
Apparently the problem was that I created an index on the custom _id field. MongoDB creates an index on that field by itself, so when Mongoose was calling ensureIndex to create also the TTL index, it failed for both.
See https://github.com/LearnBoost/mongoose/issues/2459

Categories