Skip to main content

Common Plugins

Typegoose supports mongoose plugins and this Guide will showcase how to use some plugins, more plugins or updating their versions can be done with a PR to typegoose's repository.

If the Example does not have tabs for esModuleInterop, then assume it is only written and tested for esModuleInterop: false.

mongoose-autopopulate

Last updated for:

@typegoose/typegoose@9.0.0
mongoose-autopopulate@0.14.0
npm install --save mongoose-autopopulate

Typegoose has the prop option autopopulate implemented, but it only has an effect, if mongoose-autopopulate is installed and used too.

import mongoose from 'mongoose';
import * as autopopulate from 'mongoose-autopopulate';
import { plugin, prop, Ref, getModelForClass } from '@typegoose/typegoose';

@plugin(autopopulate as any) // this is a dirty fix, because the types of this plugin don't work with "esModuleInterop: false"
class SomeClass {
@prop({ autopopulate: true, ref: 'SomeReferencedClass' })
public populateField: Ref<SomeReferencedClass>;
}

class SomeReferencedClass {
// a dummy property is required, otherwise the class will equal to others
@prop()
public dummy?: string;
}

const SomeClassModel = getModelForClass(SomeClass);
const SomeReferencedClassModel = getModelForClass(SomeReferencedClass);

(async () => {
await mongoose.connect(`mongodb://localhost:27017/`, { dbName: 'guides' });

const reference = await SomeReferencedClassModel.create({ dummy: 'hello' });
const { _id: id } = await SomeClassModel.create({ populateField: reference } as SomeClass);

console.log(await SomeClassModel.findById(id).exec()); // output will be populated

await mongoose.disconnect();
})();
caution

If you have a ref which refers back to its own class/model, like having a User class with a createdBy field referring back to User, then you'll need to set the maxDepth prop of autocomplete to 1. If you don't do this, Mongoose will do recursive calls to the user collection 10 times, extremely delaying the output of the query. Below is an example of how to set maxDepth.

// the types of "autopopulate" may change depending on the tsconfig option "esModuleInterop"
@plugin(autopopulate as any) // this is a dirty fix, because the types of this plugin don't work
class SomeClass {
@prop({ autopopulate: { maxDepth: 1 }, ref: 'SomeReferencedClass' })
public populateField: Ref<SomeReferencedClass>;
}

mongoose-findorcreate

Last updated for:

@typegoose/typegoose@11.0.0
mongoose-findorcreate@4.0.0
npm install --save mongoose-findorcreate

The plugin mongoose-findorcreate can easily be used with typegoose. Here's how to use it:

import { DocumentType, getModelForClass, plugin, prop, defaultClasses } from '@typegoose/typegoose';
import mongoose from 'mongoose';
import * as findorcreate from 'mongoose-findorcreate';

/**
* Result for the `findOrCreate` function from mongoose-findorcreate
*/
export interface FindOrCreateResult<T> {
created: boolean;
doc: DocumentType<T>;
}

/**
* This class contains all types for the module "mongoose-findorcreate", adjusted for typegoose
*/
@plugin(findorcreate)
export abstract class FindOrCreate {
public static findOrCreate: <T extends FindOrCreate>(
this: mongoose.Model<T>,
condition: FilterQuery<T>,
createWith?: any
) => Promise<FindOrCreateResult<T>>;
}

class SomeClass extends FindOrCreate {
@prop()
public someField!: string;
}

const SomeClassModel = getModelForClass(SomeClass);

(async () => {
await mongoose.connect(`mongodb://localhost:27017/`, { dbName: 'guides' });

console.log(await SomeClassModel.findOrCreate({ someField: 'Hello' }));
console.log(await SomeClassModel.findOrCreate({ someField: 'Hello' })); // both will give the same output

await mongoose.disconnect();
})();

A full example can be found in the typegoose-examples repository under examples/plugin-findorcreate.

mongoose-sequence

Last updated for:

@typegoose/typegoose@7.1.0
mongoose-sequence@5.0.0
npm install --save mongoose-sequence

To use mongoose-sequence, import the plugin and use it like this:

import AutoIncrementFactory from 'mongoose-sequence';

// AutoIncrement now is the instance
const AutoIncrement = AutoIncrementFactory(mongoose);

@plugin(AutoIncrement, { inc_field: '_id', start_seq: 200 })
class SomeClass extends defaultClasses.Base<number> {
@prop()
public _id: number;
}

// The Plugin options can be applied too
@plugin<mongoose.SequenceOptions>(AutoIncrement, { inc_field: '_id' }) // Note: "start_seq" is not in the "SequenceOptions" type
class SomeClass extends defaultClasses.Base<number> {
@prop()
public _id!: number;
}

For more details, see this issue.

@typegoose/auto-increment

Last updated for:

@typegoose/typegoose@11.0.0-beta.1
@typegoose/auto-increment@3.0.0
npm install --save @typegoose/auto-increment

The Typegoose project provides an auto-increment plugin for Mongoose. Here is how to use it:

AutoIncrementSimple

Always increments the field on each save

@plugin(AutoIncrementSimple, [{ field: 'someIncrementedField' }])
class SomeClass {
@prop() // does not need to be empty
public someIncrementedField: number;
}

const SomeModel = getModelForClass(SomeClass);

const doc = await SomeModel.create({ someIncrementedField: 10 });

await doc.save(); // someIncrementedField will be 11

AutoIncrementID

Only increases the field if the document is new and the counter is stored in a counter-collection (default field: _id).

@plugin(AutoIncrementID, {})
class SomeClass {
@prop()
public _id: number;

@prop() // does not need to be empty
public someIncrementedField: number;
}

const SomeModel = getModelForClass(SomeClass);

const doc = await SomeModel.create({ someIncrementedField: 10 }); // _id will be 1

note

Some or all of the listed plugins might not have a @types package, so types have to be mostly manually declared.