thisisnotabus
thisisnotabus

Reputation: 2069

Mongoose Cannot Post Data Twice

I'm trying to make a simple blog app. I can get the app to submit content to the DB on the first attempt, but if you try a second time Node crashes. I cannot figure out why.

post.js:

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

PostSchema = new Schema({title: {type: String, "default": ''},
                         content: {type: String, "default": ''}});

Post = mongoose.model('posts', PostSchema);

module.exports.Post = Post;
module.exports.PostSchema = PostSchema;

db-conn.js:

var mongoose = require('mongoose'),
    Post = require('./post').Post;

var createPost = function(newTitle, newContent){
    mongoose.connection.once('open', function(){
        var p = new Post({ title: newTitle,
                           content: newContent });
        p.save(function(err){
          if (err) throw err;
        });
     });

    mongoose.connect('mongodb://user:pass@(myIP):27017/blog', function(err){
      if (err) throw err;
    });

    mongoose.disconnect();
};

module.exports.createPost = createPost;

And then in my server.js file I just receive the title and content from the page and pass them to db-conn.js. Like I said, the first time you run createPost it runs successfully. 2nd attempt crashes. Any thoughts?

Upvotes: 0

Views: 368

Answers (2)

ChevCast
ChevCast

Reputation: 59213

There are a couple things wrong with your code so I just copied it and commented it.

var createPost = function(newTitle, newContent){
    mongoose.connection.once('open', function(){
        var p = new Post({ title: newTitle,
                           content: newContent });
        p.save(function(err){
          if (err) throw err;
        });
     });

    // This should only be happening once, usually during application setup.
    mongoose.connect('mongodb://user:pass@(myIP):27017/blog', function(err){
      if (err) throw err;
    });

    // You almost never need to call this yourself, but even if this call was
    // legit it should not be called immediately after `connect`. You haven't
    // even waited for the connection to be open before you've disconnected it.
    mongoose.disconnect();
};

The reason you pass a callback function to mongoose.connect is because mongoose.connect is asynchronous. What this means is that your mongoose.connect returns immediately after you call it and your program moves onto the next call. Meanwhile mongoose is now busy connecting to the database which takes a few seconds usually. When it's done connecting it must invoke the callback you passed in. This is how you pass in logic that will be executed at a later time when mongoose is done.

Essentially you called mongoose.connect and then mongoose.disconnect pretty much immediately. I'm not even sure your callback to mongoose.connect would get called if you called disconnect before it was done connecting.

Also, I should point out that this:

mongoose.connect('mongodb://user:pass@(myIP):27017/blog', function (err) {
    if (err) console.error(err);
    // connection is now open.
});

is exactly the same as:

mongoose.connection.once('open', function () {
    // connection is now open.
});
mongoose.connect('mongodb://user:pass@(myIP):27017/blog');

Ideally in a web application you would connect to your database at application start.

var http = require('http');
var mongoose = require('mongoose');

mongoose.connection.once('open', function () {

    http.createServer(function (req, res) {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World\n');
    }).listen(1337, '127.0.0.1');
    console.log('Server running at http://127.0.0.1:1337/');

}):

mongoose.connect(connectionString);

Upvotes: 1

user1048378
user1048378

Reputation: 305

You should only be calling

mongoose.connection.once(...

one time, and not every time a http post is received (I usually call it in the main app.js file and have it start my node/express app upon successful return). In your createpost function you should only have

  var p = new Post({ title: newTitle,
                       content: newContent });
    p.save(function(err){
      if (err) throw err;
    });  

Upvotes: 0

Related Questions