Learn

Mongoose supports the creation of methods on both instances of documents and collections of documents (the model).

  • .statics() adds static “class” methods to the model.
  • .methods() adds an instance method to documents.

Model Methods — .statics()

For example, in our poetry app we could use .statics() to create a method named firstAlphabetically.

const poemSchema = new mongoose.Schema({ ... )} poemSchema.statics.firstAlphabetically = function(callback) { return this.findOne({}).sort('title').exec(callback); }

The method is part of the model, which in this example would return the first document, after sorting the values of the title path alphabetically.

In order to use the new .firstAlphabetically method, we would call it inside runWithDatabase() on the Poem model like this:

const Poem = mongoose.model('Poem', poemSchema); runWithDatabase(async () => { Poem.create(properties)); const firstAlpha = await Poem.firstAlphabetically(); console.log(`The first poem alphabetically is: ${firstAlpha.title}. It goes like this: ${'\n'} ${firstAlpha.body}`); });

The console.log() logs the following in the terminal:

The first poem alphabetically is: One of Those Days. It goes like this: My shirt and spirit, are bent inside-out-backwards

Document Methods — .methods()

Instances of a model are documents. Documents have many of their own built-in instance methods. It is also possible to create custom document instance methods. Below, we create a method for our poem example to change the published path value to true on any document in the database.

const poemSchema = new mongoose.Schema({ ... )} poemSchema.methods.publish = function(callback) { this.published = true return this.save(); }

.save() writes the current JavaScript object as a MongoDB document.

Inside runWithDatabase() we could call .publish() on a document like this:

const Poem = mongoose.model('Poem', poemSchema); runWithDatabase(async () => { Poem.create(properties)); ... const publishIt = await Poem.findOne({ title: 'Rewrite Reality' }); console.log(publishIt.published) await publishIt.publish(); console.log(`${publishIt.title} has had its publish field changed to ${publishIt.published}`) });

Here we use .findOne to locate the poem, and then console.log() the initial publish value, which is false. We call .publish() on it and console.log() again to see that it changed. The output in the terminal for this code would look this:

false Rewrite Reality has had its publish field changed to true

Instructions

1.

Create a static method for your schema called findMostExpensive and set it equal to a function with a callback argument. Add this in the function’s body:

return this.findOne({}).sort('unitCost').exec(callback);

Create a method for your schema using the syntax magicItemSchema.methods.use and set it equal to a function with a callback argument. Add this in the function’s body:

this.totalUnits -= this.unitCost; return this.save();
2.

You can add the following code in runWithDatabase(), then enter node exercise.js in the terminal to see these methods in action:

const mostExpensive = await MagicItem.findMostExpensive(); console.log(`The most expensive object is the ${mostExpensive.item}`); console.log(`The ${mostExpensive.item} started with ${mostExpensive.totalUnits} charges.`); console.log(`Using ${mostExpensive.item}...`); await mostExpensive.use(); console.log(`The ${mostExpensive.item} has ${mostExpensive.totalUnits} charges left.`);

Sign up to start coding

Mini Info Outline Icon
By signing up for Codecademy, you agree to Codecademy's Terms of Service & Privacy Policy.

Or sign up using:

Already have an account?