Mongoose save callback doesn't fire - node.js

I'm new to mongoose and I'm having a hard time finding the issue within my code. I'm building a REST server using Sails.js and Mongoose. I have a node module (e.g. "sails-mongoose") for exporting mongoose, where I also connect to my database:
var mongoose = require('mongoose');
mongoose.connect('mongodb://#localhost:27017/fooria');
module.exports = mongoose;
And in my model.js:
var adapter = require('sails-mongoose');
var schema = new adapter.Schema({
firstname: {
type: String,
required: true,
trim: true
}
});
module.exports = {
schema: schema,
model: adapter.model('Collection', schema)
}
In my controller's create method I have:
create: function(req, res, next) {
var userData = {firstname: 'Test'};
var users = new Users.model(userData);
users.save(function(err, data){
if (err) return res.json(err, 400);
res.json(data, 201);
});
}
When running create method, the entry is saved to the Mongodb collection but the callback is never reached. Can someone please help me on this track, as I found similar questions but none helped me though. Thanks!

I suppose your are using Express. According Express docs you are calling res.json using incorrect parameters (wrong order).
Correct format:
res.json(code, data)
Example:
res.json(500, { error: 'message' })

Related

Mongoose TypeError: Schema is not a constructor I've tried solutions from other posts but no work

I am practicing with React.js and MongoDb, I tried to save some data using Mongoose but it keeps returning TypeError: Schema is not a constructor.
I tested it by using Postman not through the brower with React.js.
I have checked many of similar Stackoverflow posts but could not figure out why my code does not work.
Here is my code for Schema:
const mongoose = require("mongoose");
const ContactSchema = mongoose.Schema({
name: String,
number: Number
});
module.exports = mongoose.model("ContactData", ContactSchema);
And here is my POST request:
router.post("/create_contact", (req, res) => {
const { name, number } = req.body
let contact = new ContactData(
name,
number
);
contact.save((error, contact) => {
if (error) {
return console.error(error);
}
return res.json(contact);
});
});
No problems found with connecting to local MongoDb and running Express server.
What am I missing here? Any help will be appreciated. Thanks!
You need to use the new keyword when instantiating a new schema:
const ContactSchema = new mongoose.Schema({
name: String,
number: Number
});
I hope this helps.

Nodejs Duplicate Fields

I'm using a POST route to post data on a user's progress. I'm looking for a way to check if theres duplicate fields when posting, so I don't post multiple results
My route:
api.post('/progress', (req, res) => {
let progress = new Progress();
progress.user_id = req.body.user_id;
progress.level = req.body.level;
progress.save(function (err) {
if (err) {
res.send(err);
}
res.json({
message: 'progress saved!'
});
});
});
My Model
import mongoose from 'mongoose';
let Schema = mongoose.Schema;
let progressSchema = new Schema({
user_id: String,
level: String,
});
var levels = mongoose.model('Progress', progressSchema);
module.exports = mongoose.model('Progress', progressSchema);
Are you using MongoDB? If so, you can use mongoose module and add
unique: true,
to the field's attributes in your Progress schema. Check out the docs. Hope this helps.

Node.JS Express 4 - Mongoose Does not saving data

I am trying to save a data in MongoDB with Mongoose with Express.JS 4 and Bluebird.
What I have done is like this-
bin/www
var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
.......
.......
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function()
{// successfully connected!
console.log("Successfully Connected to Mongo-DB");
});
And getting this in console-
Successfully Connected to Mongo-DB` - So, MongoDB connected successfully
models/post.js
var mongoose = require('mongoose');
var postSchema = new mongoose.Schema({
created_by: String, //should be changed to ObjectId, ref "User"
created_at: {type: Date, default: Date.now},
text: String
});
module.exports = mongoose.model('Post', postSchema);
app.js
var Post_Data = require("./models/post");
....
....
router.get('/', function(req, res, next)
{
var Post = mongoose.model("Post");
var post = new Post({
created_by: ""+Math.random()
});
console.log( Post.create(post) );
res.render(
'index',
{
title : 'Express',
site_name : 'Our Site',
layout : 'templates/layout'
}
);
});
And after that I am getting this in console-
Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined }
But, nothing is saved, a proof for that is -
I am finding this-
After using MongoBooster.
Update-
My DB config is like this-
"MONGO_URI": "mongodb://localhost:27017/express_test",
"MONGO_OPTIONS": {
"db": { "safe": true },
"name":"express_test"
}
So, can anyone please help, why it is not saving anything?
Thanks in advance for helping.
The .create() function is a shortcut for new Model and .save(). You are trying to .create an instance of Model rather than a simple Object. See Constructing documents in Mongoose's Models documentation for their quick example.
The return from a Mongoose data function is just the promise of an asynchronous task to be run in the future, logging that is largely pointless. Use .then() to wait until the promise has been resolved.
Error handling is missing from your code as well, something could be getting thrown there. Use a .catch() for promise error handling.
Post.create({ created_by: ""+Math.random() })
.then(function (result) {
console.log('Saved' result)
})
.catch(function (err) {
console.error('Oh No', err)
})
All of this can be done with callbacks (like the Mongoose docco examples) but promises, particularly bluebird promises are nicer.
I just use this syntax combination to create and save my model:
var myPage = new LandingPage({
user:req.user,
slug: req.body.slug,
}).save(function(err,savedModel){
if(!err){
console.log(savedModel);
}
});
You are calling the wrong model in your app.js module as you are importing the model as
var Post_Data = require("./models/post"); // <-- Post_Data model never used
....
....
but creating a new Post model instance in your router implementation as
var Post = mongoose.model("Post"); // <-- different model
var post = new Post({
created_by: ""+Math.random()
});
You need to call and use the correct models. So I would suggest you re-write your app.js module to use the save() method as:
var Post = require("./models/post"); // <-- import correct Post model
....
....
router.get('/', function(req, res, next) {
var post = new Post({ created_by: ""+Math.random() });
post.save().then(function(post) {
console.log(post); // <-- newly created post
res.render('index', {
title: 'Express',
site_name: 'Our Site',
layout: 'templates/layout'
});
})
.catch(function(err) {
console.error('Oopsy', err);
});
});
if you store post schema in a variable by require then can use that variable.
var Post_Data = require("./models/post");
so can use new Post_Data no need to use var Post = mongoose.model("Post"); because you have already exported this schema module.exports = mongoose.model('Post', postSchema);
you can try this one :
var Post_Data = require("./models/post");
router.get('/', function(req, res, next)
{
var post = new Post_Data({created_by: ""+Math.random()});
post.save(function(error, data) {
if(error) {
return res.status(500).send({error: 'Error occurred during create post'});
}
return res.render('index',{
title : 'Express',
site_name : 'Our Site',
layout : 'templates/layout'
});
});
});
So it's true that if you're creating a document in memory by calling new Post(values) that you will save it with post.save(cb); rather than 'Post.create(post);, but I'm thinking that the underlying issue (though this isn't easy to be certain of based on the code you're showing) is that you're connecting with the MongoDB driver, rather than mongoose itself. Yourdb` variable isn't shown to be declared in the code you posted, so I'm making it an assumption.
That said, if I'm right, you need to call mongoose.connect or mongoose.createConnection in order for Mongoose to know it's connected to the db and save documents to it. You can pass an existing connection to mongoose, so if you're already doing so then I apologize for my erroneous assumption.

How to cascade delete using Mongoose remove middleware?

I'm trying to delete all dependencies of a schema when a DELETE request is sent to my API. Deleting goes ok, but the remove middleware, which is supposed to clean the dependencies, seems like is not even getting called.
This is my Customer schema:
var mongoose = require("mongoose"),
Schema = mongoose.Schema,
passportLocalMongoose = require('passport-local-mongoose');
var Order = require('./order');
var Customer = new Schema({
name: String,
telephone: Number,
address: String,
email: String,
seller: String
});
Customer.post('remove', function(next) {
Order.remove({ customer: this._id }).exec();
next();
});
Customer.plugin(passportLocalMongoose);
module.exports = mongoose.model("Customer", Customer);
And this is my customer route:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var isAuthenticated = require('./isAuthenticated');
var Customer = require('../models/customer');
var Order = require('../models/order');
// (...)
router.delete('/:customer_id', function(req, res) {
Customer.remove({ _id: req.params.customer_id }, function(err) {
if (err)
res.json({ SERVER_RESPONSE: 0, SERVER_MESSAGE: "Error deleting", ERR: err });
else res.json({ SERVER_RESPONSE: 1, SERVER_MESSAGE: "Customer deleted" });
});
});
// (...)
I did look this question and Mongoose Docs (Mongoose Middleware) but it's still unclear to me. I don't know what I'm missing or doing wrong.
Thanks in advance!
EDIT
This is my project's repository. Please, feel free to look into.
I finally found the solution to this. Middleware wasn't firing because you must use remove(), save(), etc on model instances, not the model itself.
Example:
Customer.remove({...}); won't work.
Customer.findOne({...}, function(err, customer) {
customer.remove();
});
will work and will do whatever is in Customer.post('remove').
Seems like this is the part you're focusing on:
Customer.post('remove', function(next) {
Order.remove({ customer: this._id }).exec();
next();
});
What you're doing wrong here is that the post hook is not given any flow control, so the next parameter is not actually a function but the document itself.
Change it up to this and you should get what you want:
Customer.post('remove', function(doc) {
Order.remove({ customer: doc._id }).exec();
});
From the docs:
post middleware are executed after the hooked method and all of its
pre middleware have completed. post middleware do not directly receive
flow control, e.g. no next or done callbacks are passed to it. post
hooks are a way to register traditional event listeners for these
methods.

node.js mongodb update error

I have a node.js website. I am using mongoose to connect with my mongodb. Adding new records works fine and find also works fine.
But when I update the record it throws the error below. I have a callback function but dont know whats wrong.
throw new Error("writeConcern requires callback")
^
Error: writeConcern requires callback
Below is my update code.
var newUser = new User();
newUser.update({ 'local.email' : emailID }, { 'local.resetkey': ResetHash }, { multi: false }, function (err, res) {
if (err) return handleError(err);
console.log('The raw response from Mongo was ', raw);
});
This is my schema...
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var crypto = require('crypto');
var safe = { w: "0" };
// define the schema for our user model
local : {
email : String,
password : String,
resetkey : String,
resetexpiry : String,
},
});
module.exports = mongoose.model('User', userSchema);
newUser is a document, but you are calling update as it is defined for the model and therefore getting a wrong argument in place of the callback
Try: User.update(... as in the mongoose API docs: Model.update(conditions, update, options, callback);
You show incomplete code for your schema.

Resources