Saving a model using mongoose [duplicate] - mongodb

I have this route defined, but any requests made to it get's stuck on 'pending' and runs forever.
When I log the code, I see 1 followed by 4, which means the code inside the find method never gets executed
# Calendar routes
router.get '/calendars', (req, res) ->
console.log '1'
Calendar.find (err, calendars) ->
console.log "2" + err
console.log "3" + calendars
res.send(err) if err
res.json(calendars)
return
console.log '4'
return
Model
mongoose = require("mongoose")
module.exports = mongoose.model("Calendar",
name: String
)
Any ideas on why this is?

Until you call mongoose.connect, your mongoose queries will simply be queued up.
Add code like this in your startup code to connect:
mongoose.connect('mongodb://localhost/test', function(err) {
if (err) {
console.error(err);
} else {
console.log('Connected');
}
});
In the connection string, replace test with the name of your database.

Related

mongoose.connect() is not creating a database?

I am using mongoose.connect() method but it couldn't created a DB ,i did even insert some documents in
db by using insertMany() but it neither giving me any error nor creating a DB as when i checked my mongo Shell todolistDB is not created .
const express = require('express')
const bodyParser = require('body-parser')
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/todolistDB', {
useNewUrlParser: true,
useUnifiedTopology: true },
function (err) {
if (err) {
console.log(err);
} else {console.log('server is connected');}})
const itemsSchema = mongoose.Schema({name: {type: String,required: true }})
const Item = mongoose.model('Item', itemsSchema)
const item1 = new Item({name: 'Welcome to your todo list!'})
const item2 = new Item({name: 'Hit + button to add new item'})
const item3 = new Item({name: '<-- click to delete a item!'})
const defaultItems = [item1, item2, item3]
app.get('/', function (req, res) {
Item.find({}, function (err, result) {
if (defaultItems.length===0) {
**even after insertmany method todolistDB is not created**
Item.insertMany(defaultItems, function (err) {
if (err) {
console.log(err);
} else {
console.log('new record inserted successfully!');}});
} else {
res.render('list', {listTitle: 'today',latestItems: result}) }
** when I used insertMany outside app.get() method then all records was inserted, I just started learning mongoDB sorry in advanced if it was a silly mistake **
detailed answer would be appreciated!
Consider the following three lines of your code:
[1] const defaultItems = [item1, item2, item3]
[2] Item.find({}, function (err, result) {
[3] if (defaultItems.length===0) {
In [2] you are doing a query, presumably it returns no results and you get to [3]. However in [3] you are referencing the fixed set defined in [1] which is of length 3. Thus the if statement in [3] is never entered.
The code is pretty fine.
mongoose.connect() call is fine. Since you are writing it in Promise form, issue is Unhandled Promise Rejection for connection failure.
Console the error, the error message would give us better glimpse.
Coming to the error possibilities, it is likely to happen if you use middleware handler app.use or router.use.
Please console the error, drop down the error message. So that I can help you further.
You Can Follow This Code
mongoose.connect('mongodb://localhost:27017/todolistDB', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false
})
mongoose.connection.on("connected", () => {
console.log("Mongodb connected")
})
mongoose.connection.on("error", errMsg => {
console.log("Error connecting database. Msg: " + errMsg)
})

Put / Update to my MongoDb with Express, immutable error of cross _id field

So I am sending data of a mission, the startdate and the finish date. However I am not able to put any changes into the database as it believes I get an immutable error with mongoDB... I would like to stick with using the .then method for my js code.
My other methods are working properly, I just can't get this update method right...
app.put('/missions/:id', function (req, res) {
if (req.user) {
model.Mission.findById(req.params.id).then(function(Mission){
console.log("req.body.secret_mission: ",req.body.secret_mission)
Mission['secret_mission'] = req.body.secret_mission;
Mission['start'] = req.body.start;
Mission['complete'] = req.body.complete;
Mission.update().then(function(){
res.set('Access-Control-Allow-Origin', '*');
res.sendStatus(201);
});
});
}else{
res.sendStatus(401);
}
});
Error I receive in the command line
I was able to use all the help provided to come up with a working solution and keep consistent to how I am calling the rest of my code. A big thanks to those that responded!!
Rather than setting the elements in my collection beforehand I am supposed to do it in the update request. Instead of calling 2 methods I used the findOneAndUpdate.
app.put('/missions/:id', function (req, res) {
if (req.user) {
model.Mission.findOneAndUpdate(
{'_id' : req.params.id},
{ $set: {"secret_mission" : req.body.secret_mission,
"start" : req.body.start},
"complete" : req.body.complete
}).then(function(err, missions){
if (err) return res.json({Error: err});
res.json(missions);
});
} else {
res.sendSatus(401);
}
});
I've cleaned up Your code:
removed req.user check to middleware,
included cors module to not to play with CORS headers in every handler
used async/await stuff to give it more synchronous look
mission/:id route handler just have concrete logic without garbage
Check this solution:
const cors = require('cors'); // install: npm i --save cors
const _ = require('lodash'); // install: npm i --save lodash
app.use(cors());
const isUserAuthorized = (req, res, next) => {
if (!req.user) return res.status(401).send();
next();
}
app.put(
'/missions/:id',
isUserAuthorized,
async (req, res) => {
try {
const mission = await model.Mission.findById(req.params.id);
if (!mission) return res.status(404).send();
mission.set(_.pick(req.body, ['secret_mission', 'start', 'complete']);
await mission.save();
res.status(201).send();
}
catch (error) {
console.log(error);
res.status(500).send();
}
});
or if You don't care if record in db exist or not, so You can just push update directly:
app.put(
'/missions/:id',
isUserAuthorized,
async (req, res) => {
try {
const data = _.pick(req.body, ['secret_mission', 'start', 'complete']);
await model.Mission.update({_id: req.params.id}, {$set: data});
res.status(201).send();
}
catch (error) {
console.log(error);
res.status(500).send();
}
});

Auth0 custom database mongodb, signup script is returning SandboxTimeoutError

I'm trying to use my own mongo database which is created in mlab in auth0 for user management. Here is the template they provided.
function create (user, callback) {
mongo('mongodb://user:pass#mymongoserver.com/my-db', function (db) {
var users = db.collection('users');
users.findOne({ email: user.email }, function (err, withSameMail) {
if (err) return callback(err);
if (withSameMail) return callback(new Error('the user already exists'));
bcrypt.hashSync(user.password, 10, function (err, hash) {
if (err) { return callback(err); }
user.password = hash;
users.insert(user, function (err, inserted) {
if (err) return callback(err);
callback(null);
});
});
});
});
}
After changing connection URI, I tried to "create" a user by providing email and password with the script. I see the following error:
[SandboxTimeoutError] Script execution did not complete within 20 seconds. Are you calling the callback function?
I followed the Debug Script they provided. Here is the log:
$ wt logs -p "myservice-eu-logs"
[12:35:27.137Z] INFO wt: connected to streaming logs (container=myservice)
[12:35:29.993Z] INFO wt: new webtask request 1478435731301.992259
[12:35:30.047Z] INFO wt: { [Error: Cannot find module '../build/Release/bson'] code: 'MODULE_NOT_FOUND' }
[12:35:30.047Z] INFO wt: js-bson: Failed to load c++ bson extension, using pure JS version
[12:36:05.080Z] INFO wt: finished webtask request 1478435731301.992259 with HTTP 500 in 35096ms
Any suggestions?
Actually, bcrypt.hashSync is a synchronous method, so the callback function is never called and the script times out.
Either use:
var hashedPwd = bcrypt.hashSync(user.password);
or
bcrypt.hash(user.password,10,function(....);

how to deal with mongodb race condition in integration test

I have a mongoose schema with a unique field and I am trying to write a backend (express) integration test which checks that POSTing the same entity twice results in HTTP 400. When testing manually behaviour is as excpected. Automatic testing however requires a wait:
it('should not accept two projects with the same name', function(done) {
var project = // ...
postProjectExpect201(project,
() => {
setTimeout( () => {
postProjectExpect400(project, done);
},100);
}
);
});
The two post... methods do as named and the code above works fine, but if the timeout is removed, BOTH requests receive HTTP 200 (though only one entity created in the database).
I'm new to those technologies and I'm not sure what's going on. Could this be a mongodb related concurrency issue and if so how should I deal with it?
The database call looks like this:
Project.create(req.body)
.then(respondWithResult(res, 201))
.catch(next);
I already tried connecting to mongodb with ?w=1 option btw.
Update:
To be more verbose: Project is a mongoose model and next is my express error handler which catches the duplicate error.
The test functions:
var postProjectExpect201=function(project, done, validateProject) {
request(app)
.post('/api/projects')
.send(project)
.expect(201)
.expect('Content-Type', /json/)
.end((err, res) => {
if (err) {
return done(err);
}
validateProject && validateProject(res.body);
done();
});
};
var postProjectExpect400=function(project, done) {
request(app)
.post('/api/projects')
.send(project)
.expect(400)
.end((err, res) => {
if (err) {
return done(err);
}
done();
});
};

Getting Time-Out Error While Posting Data

js.I am trying to create a file upload using node.js and mongodb.I am getting timeout error in posting data.The code that i use is:
app.post('/photos/new', function(req, res) {
var photo = new Photo();
req.form.complete(function(err, fields, files) {
if(err) {
next(err);
} else {
ins = fs.createReadStream(files.file.path);
ous = fs.createWriteStream(__dirname + '/static/uploads/photos/' + files.file.filename);
util.pump(ins, ous, function(err) {
if(err) {
next(err);
} else { photos.save({
filename: files.file.filename,
file: files.file.path
}, function(error, docs) {
res.redirect('/photos');
});
}
});
//console.log('\nUploaded %s to %s', files.photo.filename, files.photo.path);
//res.send('Uploaded ' + files.photo.filename + ' to ' + files.photo.path);
}
});
});
I get the following error when i click on the submit button.
Error: Timeout POST /photos/new
at Object._onTimeout (/home/nodeexmple/node_modules/connect-timeout/index.js:12:22)
at Timer.ontimeout (timers_uv.js:84:39)
Please help.
see this answer...
Error: parser error, 0 of 4344 bytes parsed (Node.js)
Also u can use req.clearTimeout() as suggested above by alessioalex.
I belive this part of your code is creating problems that u should avoid.
photos.save({
filename: files.file.filename,
file: files.file.path
}, function(error, docs) {
res.redirect('/photos');
});
Instead use like this:
var post = new Post();
post.filename=files.file.filename;
post.file=files.file.path;
And then something like this:
post.save(function(err) {
if (err)
return postCreationFailed();
req.flash('info', 'photos Succesfully Uploaded');
res.redirect('were u want to redirect');
});
Hope this solves your issue.
You are using the connect-timeout module so that is shows a message to your users in case the page takes more than X seconds to load (server-side).
It's obvious that the upload page might be taking more than that, so what you should do in your upload route is to clear the timeout like this:
app.post('/photos/new', function(req, res) {
req.clearTimeout();
...
Read more about connect-timeout on its github page.