How to properly use Mongoose models with Node.js?

advertisements

I'm trying to use mongoose to control my db logic and transactions. I already got Schema definitions and I'm exporting the models.

Howver when i try to use a model, it will fail witl a message like:

return mongoose.model('Report', reportSchema); } has no method 'find'...

This is my Model export:

module.exports = (function() {

var mongoose = require('mongoose'),
Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;

    var reportSchema = mongoose.Schema({

        category: ObjectId,
        authorName: String,
        authorEmail: String,
        text: String,
        address: String,
        coordinates: {
          type: "Point",
          coordinates: [Number,Number]
        },
        date: {
            type: Date,
            default: new Date()
        },

        comments: Array
    });

    return mongoose.model('Report', reportSchema);
});

And this is how my controller functions are coded using mongoose inside:

module.exports = (function() {

    var mongoose = require('mongoose');
    var Report = require('../models/Report');
    var Category = require('../models/Category');

    function _getReports (request,response,next) {

        var take = request.query.take;
        var skip = request.query.skip;

        Report.find({}).limit(take).skip(skip).exec(function (err,reports) {

            callback(err,reports,response);
        });
    }

    function _getReport (request,response,next) {

        var id = request.params.id;

        Report.findById({_id: id}, function (err,report) {

            callback(err,report);
        });
    }

    function _createReport (request,response) {

        var newReport = new Report();

        newReport.text = request.body.text;
        newReport.category = request.body.category;
        newReport.author = request.session.userId;

        newReport.save(function (err,savedReport) {
            callback(err,savedReport._id,response);
        });

    }

    function _updateReport (request,response) {

        var id = request.params.id;
        var update = request.body.report;

        Report.findByIdAndUpdate(id, update, function (err,foundReport) {

            callback(err,foundReport,response);
        });
    }

    function _deleteReport (request,response) {

        var id = request.params.id;

        Report.findByIdAndRemove(id, function (err,foundReport) {
            callback(err,foundReport,response);
        });
    }

    function _getReports (request,response,next) {

        var take = request.query.take;
        var skip = request.query.skip;

        Report.find({}).limit(take).skip(skip).exec(function (err,reports){

            callback(err,reports,response);
        });
    }

    function _getCategories (request,response) {

        var take = request.query.take;
        var skip = request.query.skip;

        Report.find({}).limit(take).skip(skip).exec(function (err,reports) {

            callback(err,reports,response);
        });
    }

    function _getCategoryReports (argument) {

        var _id = mongoose.Types.ObjectId(request.params.id);

        Report.find({category:id},{category:false},function (err, foundReports) {
            callback(err,foundReports,response);
        });
    }

    function _createCategory (request,response) {

        var newCategory = new Category();

        newCategory.name = request.body.name;

        newCategory.save(function (err,savedCategory) {
            callback(err,savedCategory._id,response);
        });
    }

    function _updateCategory (request,response) {

        var id = request.params.id;
        var update = request.body.category;

        Category.findByIdAndUpdate(id, update, function (err,foundCategory) {

            callback(err,foundCategory,response);
        });
    }

    function _deleteCategory (request,response) {

        var id = request.params.id;

        Category.findByIdAndRemove(id, function (err,foundCategory) {
            callback(err,foundCategory,response);
        });
    }

    function callback (err,object,response) {

            if (err)
                response.status(500).send(JSON.stringify(err));

            response.send(JSON.stringify(object));
    }

    var apiController = {
        getReports: _getReports,
        getReport: _getReport,
        createReport: _createReport,
        updateReport: _updateReport,
        deleteReport: _deleteReport,
        getCategories: _getCategories,
        getCategoryReports: _getCategoryReports,
        createCategory: _createCategory,
        updateCategory: _updateCategory
    }

    return apiController;
})();

Before this, a mongoose connection is ensured:

var connectToMongoose = function (mongoose,app) {

    var connect = function () {
        var options = { server: { socketOptions: { keepAlive: 1 } } };
        mongoose.connect( 'mongodb://localhost/data4', options);
    }

    mongoose.connection.on('connected', function () {

        console.log('Connected to db');

        app.listen(32884, function() {
          console.log("Listening at \"data4 port\" @:32884");
        });
    })

    mongoose.connection.on('error', function (err) {
      console.log(err);
    });

    mongoose.connection.on('disconnected', function () {
        console.log('Disconnected from db, attempting to connect again...');
        app.close();
        connect();
    });

    connect();
};

module.exports = connectToMongoose;

Which is invoked by require('./db/mongoose-connect.js')(mongoose,app);

What am I doing wrong?


There are a couple issues here that I caught off the bat.

First off, I don't see a mongoose.connect() line that explicitly connects your mongoose ODM to a mongo server+database. An example would be:

var mongoose = require( 'mongoose' ),
Schema =        mongo.Schema,
ObjectId =      mongo.Schema.ObjectId;

mongoose.connect( 'mongodb://localhost/db_name' );

Your schema export looks fine. But you're using an anonymous function as your export. Since you're doing that, your require statement needs to change a little:

var Report = require('../models/Report')();
var Category = require('../models/Category')();

Notice the () at the end of the require statements. You need to execute the function that you're defining as your model file's module.export.

EDIT: I see that you added your mongoose connect code. At this point, executing the module.exports function that you assign in the model file should allow your mongoose models to function as intended.