Reputation: 1
Instance methods
// define a schema
const animalSchema = new Schema({ name: String, type: String });
// assign a function to the "methods" object of our animalSchema
animalSchema.methods.findSimilarTypes = function(cb) {
return mongoose.model('Animal').find({ type: this.type }, cb);
};
Now all of our animal instances have a findSimilarTypes method available to them.
const Animal = mongoose.model('Animal', animalSchema);
const dog = new Animal({ type: 'dog' });
dog.findSimilarTypes((err, dogs) => {
console.log(dogs); // woof
});
I was reading the docs of mongoose and I'm not able to understand the work of this piece of code. Can anyone explain it to me.
Someone explain flow of this code
Upvotes: 0
Views: 4589
Reputation: 159
Change into the conventional function if you are using arrow function
Correct:
schema.methods.myMethod = async function () {
console.log('this', this);
};
Wrong:
schema.methods.myMethod = async () => {
console.log('this', this);
};
Upvotes: 0
Reputation: 257
I filled in the gaps with the Mongoose documentation so that you can run this on your own machine. The only missing piece here is to add the url
for connection.
// define a schema
const animalSchema = new mongoose.Schema({ name: String, type: String },
{
// Assign a function to the "methods" object of our animalSchema through schema options.
// By following this approach, there is no need to create a separate TS type to define the type of the instance functions.
methods: {
findSimilarTypes(cb) {
return mongoose.model('Animal').find({ type: this.type }, cb);
}
}
});
const Animal = mongoose.model('Animal', animalSchema);
// Creating 2 dogs and a cat
const dog = new Animal({ name: 'joe', type: 'dog' });
const dog2 = new Animal({ name: 'joe2', type: 'dog' });
const cat = new Animal({ name: 'bob', type: 'cat'});
mongoose.connect(url)
.then((result) => {
console.log("connected")
// Saving our animals to the database
return Animal.insertMany([dog, dog2, cat])
}).then(() => {
// Find similar animals to that of `dog`
dog.findSimilarTypes((err, dogs) => {
if (err) {
console.log(err)
} else {
console.log(dogs); // you should log two dogs, joe and joe2
}
});
})
Upvotes: 0
Reputation: 978
// define a schema
const animalSchema = new Schema({ name: String, type: String });
Define the Animal schema: what fields and features does an animal object have when saved to the database.
// assign a function to the "methods" object of our animalSchema
animalSchema.methods.findSimilarTypes = function(cb) {
return mongoose.model('Animal').find({ type: this.type }, cb);
};
Define that each object created with the animal recipe should also have a method called findSimilarTypes(callback)
.
const Animal = mongoose.model('Animal', animalSchema);
const dog = new Animal({ type: 'dog' });
dog.findSimilarTypes((err, dogs) => {
console.log(dogs); // woof
});
dog
. It has type 'dog'
Notice that dog.findSimilarTypes(cb)
also exists, as defined in the schema.dog
.Addition, to address Shauryan's additional question in the comments:
You can check for example this resource to understand what a callback funtion is: Callback function. I'll try my best to explain what happens in your example.
findSimilarTypes(cb)
is a function that takes a single parameter, which also is a function.
This guy here is a single, anonymous function.
(err, dogs) => {
console.log(dogs); // woof
}
When you pass a function as an argument, it's called a "callback". Let's see what you get when you call findSimilarTypes(cb)
with the anonymous function as the argument.
animalSchema.methods.findSimilarTypes = function(cb) {
return mongoose.model('Animal').find({ type: this.type }, cb);
};
becomes something like this (when you replace the cb
with the anonymous function):
return mongoose.model('Animal').find({ type: this.type }, (err, dogs) => {
console.log(dogs); // woof
});
Now it comes down to how Mongoose has defined its Model.find(). When it's done, it calls its second argument with the error and result of the database search. The second argument is the anonymous function we passed on earlier.
It takes a little time to twist your head around callbacks. Hope this helps!
Upvotes: 2
Reputation: 156
Schemas have a field called methods
. In that field you can insert your own functions like so:
animalSchema.methods.nameOfFunction = function() {
// Return something here
// The `this` keyword refers to the instance of the model
// I return the type here
return this.type;
};
Later when you create a instance of the Schema you can use them.
// animalSchema is the Schema we inserted the function into earlier
// create model from instance
const Animal = mongoose.model('Animal', animalSchema);
// Create ab Instance of the model
// the function added to the methods field gets added
// The dog gets created with type 'dog'
const dog = new Animal({ type: 'dog' });
// Now we can call the function
// the `this` in the function referes to `dog`
var result = dog.nameOfFunction();
// Will put out "dog"
console.log(result)
In the example you provided the function added finds all Animals with the same type as the animal created. The cb
argument of the function is a callback. Another function that gets called when mongoose finished searching.
Upvotes: 2