# How to use ES6 classes to create Mongoose schemas

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Dec 25, 2020, updated Oct 3, 2022. Topics: Node.js, Mongoose, MongoDB.
Canonical URL: https://attacomsian.com/blog/mongoose-es6-classes

> A quick guide to learn how to use ES6 classes to define a Mongoose schema in a Node.js application.

[Mongoose](https://attacomsian.com/blog/nodejs-getting-started-with-mongoose) allows us to create a schema from ES6 classes. The `loadClass()` method provided by Mongoose [Schemas](https://attacomsian.com/blog/mongoose-schemas) takes in a class object as input and copies all methods, statics, and getters/setters of the class into the `Schema` object.

A ES6 [class method](https://attacomsian.com/blog/javascript-classes#instance-methods) maps to a [schema method](https://attacomsian.com/blog/mongoose-schemas#instance-methods), a [static method](https://attacomsian.com/blog/javascript-classes#static-methods) maps to a [schema static method](https://attacomsian.com/blog/mongoose-schemas#static-methods), and [getters/setters](https://attacomsian.com/blog/javascript-classes#getters-and-setters) map to [Mongoose virtuals](https://attacomsian.com/blog/mongoose-virtuals).

To see how it works, let us first define a new ES6 class:

```javascript
class User {
    set name(name) {
        const tokens = name.split(' ');
        this.firstName = tokens[0];
        this.lastName = tokens[1];
    }

    get name() {
        return `${this.firstName} ${this.lastName}`;
    }

    static findByLastName(lastName) {
        return this.find({ lastName: new RegExp(lastName, 'i') });
    }
}
```

You can now use the `loadClass()` method to pull in methods, statics, and getters/setters from the `User` class into a Mongoose schema:

```javascript
const schema = new Schema({
    firstName: String,
    lastName: String
});

schema.loadClass(User);

console.log(schema.methods);    // {}
console.log(schema.statics);    // { findByLastName: [Function: findByLastName] }
console.log(schema.virtuals);   
// {
//     name: VirtualType {
//       path: 'name',
//       getters: [ [Function: get name] ],
//       setters: [ [Function: set name] ],
//       options: {}
//     }
// }
```

As you can see above, we have used an ES6 class to add static and virtual methods to a Mongoose schema. Using the ES6 class notation makes your code easier to read and maintain, especially when you need to add a lot of methods, statics, and virtuals to a schema.

After the import is finished, you can [define a model](https://attacomsian.com/blog/mongoose-schemas#creating-a-model) and start writing different queries:

```javascript
const Person = mongoose.model('Person', schema);

// Create new document
const alex = new Person({ name: 'Alex Jones' });
// { _id: 5fe6521b6fe6a151b56104c4, firstName: 'Alex', lastName: 'Jones' }

// Fetch documents by the last name
Person.findByLastName('Shah')
    .then(docs => console.log(docs))
    .catch(err => console.log(err));
```

Read [this guide](https://attacomsian.com/blog/javascript-classes) to learn more about classes in JavaScript.
