简体   繁体   中英

Node JS MongoDB Not Saving

I am new to Node JS so I might be missing something fairly obvious. I recently have been trying to save some data to a DB with mongoose, but I have been unsuccessful in my attempts. Although the server tells me it is saved, there is no trace of the data in my database.

app.js (relevant portion of code near the bottom)

/* REQUIRES */
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var ejs = require('ejs');
var moment = require('moment');
var app = express();
var router = express.Router();
var port = 80;
moment().format();

/* MONGOOSE CONNECT & MODEL */
mongoose.connect('mongodb://127.0.0.1:27017/giveaway');
var Giveaway = require('./models/giveaway');
var Entry = require('./models/entry');

/* EXPRESS APP LISTEN */
app.listen(port, function() {
  console.log('Magic happens on port %s.', port);
});

/* VIEW ENGINE, MIDDLEWARE SETUP, AND STATIC FILES */
app.set('view engine', 'html');
app.engine('html', ejs.renderFile);
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({ extended: false }));

router.get('/:giveawayId', function(req, res, next) {
  var giveawayId = req.params.giveawayId;
  Giveaway.find({ _id: giveawayId }, function(err, giveaway) {
    if (err) throw err;
    if (Object.keys(giveaway).length < 1) {
      /* NO GIVEAWAY WITH THAT TITLE */
      console.log("error");
      next();
    } else {
      res.render('pages/giveaway', { giveaway: giveaway });
    }
  });
});

router.post('/:giveawayId/enter', function(req, res, next) {
  var giveawayId = req.params.giveawayId;
  var name = req.body.name;
  var email = req.body.email;
  if (name !== "" && email !== "") {
    Entry.findOne({ email: email }, function(err, entry) {
      if (err) throw err;
      if (entry !== null) {
        /* ALREADY ENTERED */
        console.log("error");
        console.dir(entry);
        next();
      } else {
        console.log("success");
          var newEntry = new Entry({
            name: name,
            email: email,
            giveaway: giveawayId
          });
          newEntry.save(function(err) { //PROBLEM IS HERE WHERE IT SAVES THE DATA
            if (err) throw err;
            res.redirect('/' + giveawayId);
          });
      }
    });
  }
});

app.use('/', router);

entry.js (relevant model)

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

var entrySchema = new Schema({
  name: String,
  email: String,
  giveaway: String,
  dateEntered: Date,
  winner: {
    type: Boolean,
    'default': false
  }
});

entrySchema.pre('save', function(next) {
  if (!this.dateEntered) {
    this.dateEntered = new Date;
  }
  next();
});

var Entry = mongoose.model('Entry', entrySchema);
module.exports = Entry;

The code near the bottom of the app.js where the enterer is saved to the db is where the problem is. I'm assuming it is some sort of async error that I am overlooking but all help would be appreciated. Another piece of info that might be helpful is the output of the entry variable. Even though the data doesn't show up in the DB, it shows up as the result to the query.

error
model {
  '$__': 
   InternalCache {
     strictMode: true,
     selected: undefined,
     shardval: undefined,
     saveError: undefined,
     validationError: undefined,
     adhocPaths: undefined,
     removing: undefined,
     inserting: undefined,
     version: undefined,
     getters: {},
     _id: undefined,
     populate: undefined,
     populated: undefined,
     wasPopulated: false,
     scope: undefined,
     activePaths: StateMachine { paths: [Object], states: [Object], stateNames: [Object] },
     ownerDocument: undefined,
     fullPath: undefined,
     emitter: EventEmitter { domain: null, _events: {}, _eventsCount: 0, _maxListeners: 0 } },
  isNew: false,
  errors: undefined,
  _doc: 
   { __v: 0,
     giveaway: 'NyX2sanGx',
     email: 'test',
     name: 'test',
     dateEntered: Wed Nov 11 2015 19:13:50 GMT-0800 (PST),
     _id: ObjectID { _bsontype: 'ObjectID', id: 'VD\u0003î½åwÑ89ì' } },
  '$__original_save': { [Function] numAsyncPres: 1 },
  save: [Function: wrappedPointCut],
  _pres: { '$__original_save': [ [Object], [Object], [Object] ] },
  _posts: { '$__original_save': [] } }

Thanks, Cameron Jones

EDIT: Just to confirm, the other time I save data it shows up inside of the database no problem at all. It is just the last one that is acting up.

Leaving Mongoose aside for a second, and lets try to model this on Mongo first.

Your goal is to allow 1 email entry per giveaway so you first create unique index:

db.entry.ensureIndex({email:1, giveaway:1}, {unique:true});

Next, to do everything atomically , you would use upsert (update or insert)

Edit: removing $set portion

db.entry.update({
    email: 'me@me.com',
    giveaway: 1
}, {
    $setOnInsert: {
        name: 'John',
        email: 'me@me.com',
        giveaway: 1,
        created: ISODate()
    }
}, {
    upsert: true
});

This means: try to find user with email me@me.com and giveaway 1 , when not found then create new entry with name, email, giveaway, created and modified date.

To see your record:

db.entry.findOne()

{
    "_id" : ObjectId("56441446e480d6b501bd0a93"),
    "created" : ISODate("2015-11-12T04:23:34.086Z"),
    "email" : "me@me.com",
    "giveaway" : 1,
    "name": "John"
}

Mongoose has support for $setOnInsert

var options = {
    upsert: true,
    'new': true,
    setDefaultsOnInsert: true
};
var find = {
    email: 'me@me.com',
    giveaway: 1,
};
var setOnInsert = {
    email: 'me@me.com',
    giveaway: 1,
    name: 'John',
    created: new Date()
};
Entry.findOneAndUpdate(find, {$setOnInsert: setOnInsert}, options);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM