Reputation: 1788
I'm pretty new to web development and coming from a java/android background. I read all other so questions regarding mongoose save() not saving to db but still can't get this to write into the db.
Thank you!
I wrote grocery.js which defines my schema and I wrote another script groceryQueries.js to write and read into the database. The save prehook is called, however the save posthook isn't. This is the command I use:
node groceryQueries.js insert fruits,apple,appl.jpg,.46
Here is the output:
(node:14548) DeprecationWarning:
open()
is deprecated in mongoose >= 4.11.0, useopenUri()
instead, or set theuseMongoClient
option if usingconnect()
orcreateConnection()
. See http://mongoosejs.com/docs/connections.html#use-mongo-clientconnected to mongodb
params: fruits,apple,appl.jpg,.46 (node:14548) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
saving apple
grocery.js:
var mongoose = require('mongoose');
var grocerySchema = new mongoose.Schema({
name: {
type: String,
unique: false,
required: true,
trim: true
},
img: {
type: String,
unique: false,
required: false,
trim: true
},
price: {
type: Number,
unique: false,
required: true,
trim: true
},
category: {
type: String,
unique: false,
required: true,
trim: true
}
});
grocerySchema.pre('save',function(next) {
var grocery = this;
console.log("saving "+grocery.name);
next();
});
grocerySchema.post('save',function(next) {
console.log("post saving ");
next();
});
grocerySchema.statics.COLLECTION_NAME = function() {
return 'groceries';
}
grocerySchema.methods.toString = function() {
console.log(Grocery.COLLECTION_NAME() + ", Category: " + this.category + " is " + this.name+" and costs "+this.price+"");
};
var Grocery = mongoose.model('groceries',grocerySchema);
module.exports = Grocery;
groceryQueries.js:
var mongoose = require('mongoose');
var url = "mongodb://localhost:27017/deliveryservice";
mongoose.connect(url);
const Grocery = require('../server/models/grocery');
var db = mongoose.connection;
db.on('error',console.error.bind(console,'connection error'));
db.once('open',function() {
console.log("connected to mongodb");
doQueries();
});
function doQueries() {
var groceryCollection = Grocery.COLLECTION_NAME();//"groceries";
var arg = process.argv[2];
if (arg == 'find' ||
arg == 'insert') {
if (arg == 'find') {
var nameArg = process.argv[3];
if (nameArg === undefined) {
var error = new Error('undefined name');
throw error;
}
Grocery.find({name: nameArg},function(err,groceries) {
if (err) {
return console.error(err);
}
console.log("groceries: " + groceries);
db.close();
});
} else if (arg == 'insert') {
var paramsArg = process.argv[3];
var throwError = false;
if (paramsArg === undefined) {
throwError = true;
}
console.log("params: "+paramsArg);
var parameters = paramsArg.split(",");
if (parameters.length != 4) {
throwError = true;
}
if (throwError) {
var error = new Error('undefined parameters <name>,<img>,<price>');
throw error;
}
var newGrocery = new Grocery({category: parameters[0],name: parameters[1], img: parameters[2], price: parameters[3]});
//console.log("before save: "+newGrocery.toString());
newGrocery.save(function(err,newGrocery) {
if (err) {
throw err;
}
grocery.toString();
});
db.close();
}
} else {
console.log('help: find <name> | insert <category>,<name>,<img>,<price>')
}
}
Upvotes: 0
Views: 1600
Reputation: 772
The main problem in your code is that you are closing the connection to the db before the saving occurs. Note that all db operations in mongoose are asynchronous and calling an asynchronous function just schedules the operation for the next tick of the event loop.
You want to do this instead:
newGrocery.save(function(err, newGrocery) {
if (err) {
throw err;
}
// grocery.toString(); <- typo here btw, param is called newGrocery
}).then(function() {
db.close();
});
And delete next
from your post-save hook, that parameter is actually the saved grocery and you should not call it like a function.
grocerySchema.post('save', function() {
console.log('post saving ');
})
Bonus
To get rid of the warning about open() and connect() being deprecated use this to opt-in to the new connection logic:
mongoose.connect(url, {
useMongoClient: true,
});
To get rid of the warning about promises add this after requiring mongoose:
// Use native promises
mongoose.Promise = global.Promise
Upvotes: 0
Reputation: 331
save
returns a promise, which you have to wait for:
newGrocery.save(function(err,newGrocery) {
if (err) {
console.log(err);
throw err;
}
newGrocery.toString(); // you had a typo here btw
}).then(function() { db.close();});
Your code runs db.close()
before mongoose had a chance to save anything.
Upvotes: 1