Mongoose findBiId - node.js

I am working on a real estate project. The property's model is:
const propertySchema = new mongoose.Schema({
owner:{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
title: {
type: String,
require: true,
},
address: {
type: String,
require: true,
},
secondAddress: String,
city: {
type: String,
require: true,
},
state: {
type: String,
require: true,
},
zip: {
type: String,
require: true,
},
});
When I try to get the information of a specific property I get the error Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer. If I hardcode the id everything works. The route to get to the property is:
router.get('/property/:id', async(req, res) => {
const property = await Property.findById(req.params.id)
res.render('pages/user/property', { property })
})
How should I approach this?

You need _id in your schema in order to use findById, but you don't have one.
See documentation here,
and also this answer by JohnnyHK

Related

'number' only refers to a type, but is being used as a value here

src/db/models/point.ts:10:11 - error TS2693: 'number' only refers to a type, but is being used as a value here.
const PointSchema: Schema = new Schema({
id: {
type: String,
required: true,
unique: true,
index: true,
},
point: {
type: number,
required: true,
},
});
export interface PointProp extends Document {
id: string;
point: number;
}
export default model<PointProp>('point', PointSchema);
You are using a TypeScript type inside an object, as value, just as what the error says. You should have given more info, but I am guessing you are working with Mongoose. In that case, number (the TypeScript type) should be Number (the object)
const PointSchema: Schema = new Schema({
id: {
type: String,
required: true,
unique: true,
index: true,
},
point: {
type: Number, // <---
required: true,
},
});
See https://mongoosejs.com/docs/guide.html#definition for more information.
It's just a typo. change number to Number
point: {
type: **Number**,
required: true,
},

How to use virtual on a nested field in mongoose

I am using mongoose in node.js. I have the following Schema.
const CustomerSchema = new mongoose.Schema({
...
email: {
type: String,
required: true,
lowercase: true,
trim: true
},
addresses: [
{
addressType: {
type: String,
enum: [ 'personal', 'shipping', 'billing' ]
},
street: {
type: String,
required: true,
trim: true
},
streetNumber: {
type: String,
trim: true
},
floor: {
type: String,
trim: true
},
apartament: {
type: String,
trim: true
},
cp: {
type: String,
required: true,
trim: true
},
district: {
type: String,
trim: true
},
city: {
type: mongoose.Schema.ObjectId,
ref: 'City',
required: true
}
}
]
});
I want to use "virtuals" to "add" a new field in every object in the array addresses?
How I can do this using virtuals? Is it possible?
I can achieve the same result using, but I would like to use virtuals.
const customerDB = await Customer.findById(idCustomer).lean()
customerDB.addresses = customerDB.addresses.map((address) => ({
...address,
addressDesc: mapTypeAddressDescription(address.addressType)
}));
Many Thanks!
As the name suggests virtuals are not added to the MongoDB documents. They are used for computed properties on documents.
Suppose you have a User model. Every user has an email, but you also want the email's domain. For example, the domain portion of 'test#gmail.com' is 'gmail.com'.
Below is one way to implement the domain property using a virtual. You define virtuals on a schema using the Schema#virtual() function.
const userSchema = mongoose.Schema({
email: String
});
// Create a virtual property `domain` that's computed from `email`.
userSchema.virtual('domain').get(function() {
return this.email.slice(this.email.indexOf('#') + 1);
});
const User = mongoose.model('User', userSchema);
let doc = await User.create({ email: 'test#gmail.com' });
// `domain` is now a property on User documents.
doc.domain; // 'gmail.com'
You should check the documentation for more details.
You can do something like this:
CustomerSchema.path('addresses').schema.virtual('fullAddr').get(function() {
return 'foo'
})
Also, it is useful to check this answer on stackoverflow if the above one doesn't work.

Calculating the length of a schema and storing it in the data base

I am using node.js express.js and mongoose to develop my back end, I have this mongoose schema where I want to add a field called NumberRecords for every stored document this field will have the length value of the array csvData, I looked around some similar question here and I found I can use this pre function which I did but I get nothing on my database no field called NumberRecords is being added.
How do I fix this?
const rowSchema = new mongoose.Schema({
SESSION_ID: {
type: String,
required: false,
},
CARD_NUMBER: {
type: String,
required: false,
},
TERMINAL_ID: {
type: String,
required: false,
},
EXTERNAL_STAN: {
type: String,
required: false,
},
})
const csvSchema = new mongoose.Schema(
{
fileName: { type: String, required: true },
csvData: { type: [rowSchema], required: true },
NumberRecords: { type: Number, required: true },
},
{
timestamps: true,
}
);
csvSchema.pre("validate", function (next) {
this.NumberRecords = this.csvData.length;
next();
});
module.exports = mongoose.model("csvRecords", csvSchema);

Mongoose query through the element inside the array

I have a mongoose model:
let schema = new Schema({
email: {
type: String,
required: true,
unique: true
},
password: {
type: String
},
username: {
type: String,
unique: true
},
confirmed: {
type: Boolean
},
payload: [{
type: {
token: blablabla,
type: blablabla
}
}]
});
And i want find user by payload.token. How can I do that? I tried $elemMatch, but it does not work.
You can do
.find({'payload.type.token': token})
If payload is an array of objects and you want to find users by token value , below query should work :
db.users.find({payload: {$elemMatch: {'type.token':'blablabla'}}});

Mongoose - how to create portable documents with fixed type

Given the goal of having a JSON object that can be passed to a consumer where the json object contains some variation of:
{
_id: 1
name: "my_name",
type: "my_type",
my_particulars: {
value: 1,
author: "some author"
}
}
such that the "type" value is locked into the schema/model is there an established pattern for satisfying this requirement?
It seems to me that the best options is some form of:
var WidgetSchema = new Schema({
//Name
name: {type: String, required: true, unique: true},
type: {type: String, required: true, default: "widget"},
title: {type: String, required: true },
description: { type: String, required: true },
//Status 1: Not Live
//Status 2: Live
status: {type: Number, required: true, default: 1}
});
WidgetSchema.virtual('type').set(
function () {
return false;
});
Instead of actually storing the type you can add it as a virtual property which is returned with the JSON. Something like:
WidgetSchema.virtual('type').get(function () {
return 'widget';
});
With this defined, you can instruct mongoose to include virtuals in the toObject/toJSON output by passing the virtuals option.
// either directly to the method
instanceOfWidget.toJSON({virtuals: true});
// or as a default by setting the option on the schema
WidgetSchema.set('toObject', {virtuals: true});

Resources