0

I'm experimenting with Node, Express and Mongoose. Here's part of my model -- book-model.js which exports its schema and methods for use in a controller. I'm implementing the fat model, skinny controller approach:

// ...

BookSchema.statics.create = function(title, author, category, callback) {
    var Book = mongoose.model('Book');
    Book.create({
        title: title,
        author: author,
        category: category
    }, callback);
};

// ...

module.exports = mongoose.model('Book', BookSchema);

And here's part of the controller -- books-controller.js:

// ...

var Book = require('./book-model');

router.post('/', function(req, res) {
    var title = req.body.title,
        author = req.body.author,
        category = req.body.category;
    Book.create(title, author, category, function(err) {
        if (err) {
            console.log(err);
            res.redirect('/add-book');
        }
        res.redirect('/books');
    });
});

// ...

Now, when I attempt to create a new book document, I get the annoying Maximum call stack size exceeded message. I had a look at a similar question here on SO: Maximum call stack size exceeded error and the answer is that "Somewhere in your code, you are calling a function which in turn calls another function and so forth, until you hit the call stack limit. This is almost always because of a recursive function with a base case that isn't being met."

I can't see a recursive function in the books-controller.js file that has a base case that isn't being met or what is it that I'm missing?

Please advise.

Community
  • 1
  • 1
Zero
  • 717
  • 6
  • 21
  • I could be off, but it looks like whenever you make a book for the first time, it redirects to this same function again after the first time is done. – Matt Jones Oct 13 '14 at 17:32
  • Does that error refer to a line number? What does the call stack look like? You should be able to see the what's being called over and over from that. – Alex Wayne Oct 13 '14 at 17:33
  • What's the handler for `'/books'`? If you redirect there, that could be part of the problem. – Raphael Serota Oct 13 '14 at 17:35
  • I'm receiving nothing from the console apart from a `500` status code. `/books' is handled by a GET method and that's where I get to see a list of all the books. – Zero Oct 13 '14 at 17:46

1 Answers1

2

Here's your recursion:

BookSchema.statics.create = function(title, author, category, callback) {
    var Book = mongoose.model('Book');
    Book.create({
        title: title,
        author: author,
        category: category
    }, callback);
};

Basically, you're declaring a Book.create method that calls Book.create. Since javascript doesn't have operator overloading, it doesn't realize that your redefinition conflicts with the older Book.create that takes only two arguments.

Rename the function to something else like make to break the recursion:

BookSchema.statics.make = function...
slebetman
  • 109,858
  • 19
  • 140
  • 171
  • Or for hilarity `Book.crrrreate` to remind you that this version has four arguments :) – slebetman Oct 13 '14 at 17:55
  • This worked. Strangely, I'm left even more confused. Because you see, I've also got an Album model that has an `AlbumSchema.statics.create` method and also uses `Album.create`, and I've had no recursion problems with it. Since I wired the Album model first and things worked that way, I figured I won't have any issues with `BookSchema.statics.create` and `Book.create`. Anyway, thanks! – Zero Oct 13 '14 at 17:58