Skip to content

Recipes

Francis Wertz edited this page Jul 14, 2016 · 4 revisions

Decorators

  • @model
  • @schema
  • @method
  • @pre / @post
  • @statics
  • @virtual
  • @plugin

Simple @model, with @schema

import mongoose from 'mongoose';
import {model,schema} from 'mongoose-decorator';

@model( 'task' )
class Task extends mongoose.Schema {
    @schema
    schema() {
        // Declare Schema as normal
        return {
            name: String,
            owner: { type: mongoose.Schema.Types.Oid, ref: 'user' },
            completed: { type: Boolean, default: false },
            due: Date
        }
    }
};

export default Task;

Mongoose plugins using @plugin

import mongoose from 'mongoose';
import mongoose-deep-populate from 'mongoose-deep-populate';
import {model,plugin} from 'mongoose-decorator';
let deep = mongoose-deep-populate( mongoose );

@model( 'user' )
@plugin( deep )
class User extends mongoose.Schema {
    ...
}

Using @method, @virtual, and @statics

import mongoose from 'mongoose';
import {model,schema,method,virtual,statics} from 'mongoose-decorator';

@model( 'user' )
class User extends mongoose.Schema {
    @schema
    schema() {
        return {
            firstName: String,
            lastName: String,
            geocode: mongoose.Schema.Types.Mixed,
            friends: { type: mongoose.Schema.Types.Oid, ref: 'user' }
        }
    }

    @method
    findNearbyRestaurants( dist ) {
        let $position = this.get( '$position' );
        return POI.find({    
            geo: {
                $near: $position,
                $maxDistance: dist
            }
        }).limit( 10 ).exec();
    }

    @method
    friendsOfFriends() {
        return this.deepPopulate( 'friends friends.friends' ).exec();
    }

    @virtual( '$position' )
    geoPosition() {
        var {latitude,longitude} = this.get( 'geocode.location' );
        return [longitude,latitude];
    }

    @statics
    static Genders() {
        return ['Male', 'Female', 'Fluid', 'Flavor of the week'];
    }
}

Triggering hooks with @hooks

Hooks and middleware in mongoose are somewhat convoluted. @hooks doesn't intend to clear any of that mess up, but rather intends to simply ease their definition within your class structure.

Supported Hooks
  • init
  • validate
  • save
  • remove
  • find
  • update
import mongoose from 'mongoose';
import {model,pre,post} from 'mongoose-decorator';

import User from './moodels/user'; 

@model
class SomeModel extends mongoose.Schema {
    @post
    init( doc ) { ... }
    
    @pre
    save( next ) {
        this.set( 'updatedAt', new Date ); next();
    }
    
    @pre( 'save' )
    anotherSaveHook( next ) { ... }
    
    @post( 'remove' )
    onAfterRemove( doc ) {
        User
            .FindAllAndRemoveFriend( doc.id )
            .then( yass => { ... })
            .then( ( null, uhoh ) => { ... } )
    }
}