Nodejs Mongoose - TypeError: Invalid sort() argument

Problem

Hi I am trying to run my program, but when I try to connect to localhost in my browser I get the following error each time. I assume it's something wrong with my sorting or querying but I'm not really sure where exactly it's going wrong. Can anyone help fix my code? Is the app.js code correct as well, I feel there may be an error there too..? Any help welcome! :)

Express
500 TypeError: Invalid sort() argument. Must be a string or object.
at Query.sort (C:\nodeapps\nodeblox\node_modules\mongoose\lib\query.js:1167:11)
at Function.Post.statics.getAll (C:\nodeapps\nodeblox\schemas\Post.js:44:9)
at module.exports.app.post.username (C:\nodeapps\nodeblox\routes\index.js:45:10)
at callbacks (C:\nodeapps\nodeblox\node_modules\express\lib\router\index.js:160:37)
at param (C:\nodeapps\nodeblox\node_modules\express\lib\router\index.js:134:11)
at pass (C:\nodeapps\nodeblox\node_modules\express\lib\router\index.js:141:5)
at Router._dispatch (C:\nodeapps\nodeblox\node_modules\express\lib\router\index.js:169:5)
at Object.router (C:\nodeapps\nodeblox\node_modules\express\lib\router\index.js:32:10)
at next (C:\nodeapps\nodeblox\node_modules\express\node_modules\connect\lib\proto.js:190:15)
at Object.methodOverride [as handle] (C:\nodeapps\nodeblox\node_modules\express\node_modules\connect\lib\middleware\methodOverride.js:37:5)

Here are my 2 Schemas which I assume is causing the issue

Post.js

'use strict';

var util = require('util');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var validatePresenceOf = function(value){
  return value && value.length; 
};

var toLower = function(string){
  return string.toLowerCase();
};

var getId = function(){
  return new Date().getTime();
};

/**
  * The Post schema. we will use timestamp as the unique key for each post
  */
var Post = new Schema({
  'key' : {
    unique : true,
    type : Number,
    default: getId
  },
  'subject' : { type : String,
                validate : [validatePresenceOf, 'Subject is Required']
              },
  'content' : {type : String},
  'author': String,
  'tags' : {
            type : String,
            set : toLower
           }
});

/**
  * Get complete post details for all the posts
  */
Post.statics.getAll = function(cb){
  var query = this.find({});
  query.sort('key', -1);
  return query.exec(cb);
};

/**
  * Get only the meta information of all the posts.
  */
Post.statics.getAllMeta = function(cb){
  return this.find({}, ['key','subject', 'author', 'tags'], cb);
};

Post.statics.findByKey = function(key, cb){
  return this.find({'key' : key}, cb);
};

module.exports = mongoose.model('Post', Post);

User.js

'use strict';

var util    = require('util');
var bcrypt  = require('bcrypt');
var mongoose = require('mongoose');
var Schema   = mongoose.Schema;

var validatePresenceOf = function(value){
  return value && value.length; 
};

var toLower = function(string){
  return string.toLowerCase();
};

var getId = function(){
  return new Date().getTime();
};

var User = new Schema({
  'key' : {
    unique : true,
    type : Number,
    default: getId
  },
  'username' : { type : String, 
              validate : [validatePresenceOf, 'a Username is required'],
              set : toLower,
              index : { unique : true }
              },
  'password' : String,
});

User.statics.findUser = function(username, cb){
  return  this.find({'username' : username}, cb);
};

User.statics.validateUser = function(username, password, cb){
  this.find({'username' : username}, function(err, response){
    var user = response[0];
    if(!user || response.length === 0){
      cb(new Error('AuthFailed : Username does not exist'));
    }else{
      if(password == user.password){
        util.log('Authenticated User ' + username);
        cb(null, user);
      }else{
        cb(new Error('AuthFailed : Invalid Password'));
      }
    }
  });
};

module.exports = mongoose.model('User' , User);

And finally my app.js

'use strict'

/**
 * Module dependencies.
 */
var express = require('express');
var util    = require('util');
var Logger = require('devnull');
var logger = new Logger({namespacing : 0});
var mongoose = require('mongoose');
var http = require('http');
var app  = express();

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

/**
  * Application Configuration
  */
app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.enable('jsonp callback');
  app.set('view engine', 'jade');
  app.set('view options', {layout : false});
  app.use(express.bodyParser());
  app.use(express.cookieParser());
  app.use(express.session({
    secret : 'devadotD'      
  }));
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
  app.use(function(req, res, next){
    res.locals.session = req.session;
    next();
  });
});

/**
  * Application environment(s) Configuration
  */
app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
});

app.configure('stage', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
});

app.configure('production', function(){
  app.use(express.errorHandler()); 
});

// Routes
require('./routes')(app);

http.createServer(app).listen(app.get('port'), function(){
  util.log("Express server listening on port " + app.get('port'), app.settings.env);
  logger.log("Express server listening on port " + app.get('port'), app.settings.env);
});

module.exports = app; 
Problem courtesy of: germainelol

Solution

You are most likely using a newer version of mongoose than your code was written for. The .sort() method has been updated and it now takes parameters like this, for descending order:

query.sort('-key');

Or you can use this version:

query.sort({key: -1});

Whichever you use, yours is outdated. See the latest docs.

Solution courtesy of: Victor Stanciu

Discussion

There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.