NodeJS Mongoose not working properly - node.js

I have a problem with NodeJS and Mongoose. The connection to the DB stands but I can't get any data from there. I can connect to /api/buckets as well with no problems. Here is my code:
app.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
Bucket = require('./models/bucket');
// Connect to Mongoose
mongoose.connect('mongodb://localhost/worldbucket', function (err) {
if (err) throw err;
console.log('Successfully connected');
});
app.get('/', function (req, res) {
res.send('Please use sth other');
});
app.get('/api/buckets', function (req, res) {
Bucket.getBuckets(function (err, buckets) {
console.log("funkt");
if (err) {
throw err;
}
res.json(buckets);
});
});
app.listen(3000);
console.log('Running on port 3000');
and bucket.js:
var mongoose = require('mongoose');
// Bucket Schema
var bucketSchema = mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
creator: String,
text: String,
fulfilment: String,
latitude: Number,
longtitude: Number
});
var Bucket = mongoose.model('bucket', bucketSchema);
module.exports = Bucket;
// get Buckets
module.exports.getBuckets = (callback, limit) => {
Bucket.find(callback).limit(limit);
}
I hope you can help me.
Thanks in advance

Im not sure what version of mongoose you using, but from their docs
http://mongoosejs.com/docs/queries.html
// With a JSON doc
Person
.find({
occupation: /host/
})
.limit(10)
.sort({ occupation: -1 })
.select({ name: 1, occupation: 1 })
.exec(callback);
So in your case should be
Bucket.find({}).limit(limit).exec(callback);
Hope this helps.

Check the name of your collection in mongo - it should be called buckets not bucket. It needs to be plural. Apart from that your code works, I have tested it.👍🏻
> db
worldbucket
> db.buckets.insert({"creator":"me","text":"hello world"})
WriteResult({ "nInserted" : 1 })
> db.buckets.find()
{ "_id" : ObjectId("5a0a154a29642fd7a970420e"), "creator" : "me", "text" : "hello world" }
$ curl http://localhost:3000/api/buckets
[{"_id":"5a0a154a29642fd7a970420e","creator":"me","text":"hello world"}]
There is another SO thread on this topic here: Why does mongoose always add an s to the end of my collection name

Related

Issue with fetching value from mongodb using mongoose it always returns [ ]

I'm trying to learn mongoose with nodejs and created a following node function as below where in I'm receiving the email ID from the Angular application and based on the EmailId trying to find the records in MongoDb:
const express = require('express');
const mongoose = require('mongoose');
var bodyParser= require("body-parser");
const port = 3000;
const app = express();
//setting up bodyParser middleWare
app.use(bodyParser.urlencoded({"extended":true}))
app.use(bodyParser.json());
//setting mongoose connection to local mongoDb
mongoose.connect("mongodb://127.0.0.1/userDetails",{useNewUrlParser:true,useUnifiedTopology:true})
const db = mongoose.connection;
var userSchema = new mongoose.Schema({
email:{type:String},
userId:{ type: String, required: true },
password:{ type: String, required: true }
});
var users = mongoose.model('User', userSchema);
//error handler middleWare
app.use(function(err, req, res, next) {
console.error(err.stack)
res.status(500).send('Something broke!')
});
app.post("/login",async(req,res,next)=>{
try {
await users.find({ email:"xyz#gmail.com"}).exec(function (err, docs) {
if (err){
console.log(err);
}
else{
console.log("First function call : ", docs);
}
})
}
catch(err){
next(err);
}
})
app.listen(port,()=>{console.log("server started")});
The above code shows no error, but the output is always First function call : [].My mongodb collection is as follows
db.User.insertMany([
{ email: "xyz#gmail.com", userId:1,password : "123#124" },
{ email: "abc#yahoo.com",userId:2,password : "123#125"},
{ email: "lmn#outlook.com", userId:3,password : "123#126"}
])
db.User.find({ email: "xyz#gmail.com"});
Where is that I'm going wrong ,what should be the approach to get the data?
Your code should find and print the data to the console assuming the email address you're looking for is actually in the collection. However, I want to point out a few things that don't quite make sense.
There is absolutely no reason to await the function call await users.find({ email:"xyz#gmail.com"}).... So you should change it to users.find({ email:"xyz#gmail.com"})
With that change, there is absolutely no reason for the router function to be async. So this is how it should look app.post("/login", (req, res, next) => {...
You're not sending a response back to the caller of /login. So when you test, it just hangs there until you cancel your request. You should add res.json({msg: 'ok'}) below console.log("First function call : ", docs);
And finally, mongoose is an awesome, promise-based library. Why not use its promise capability? It will greatly clean up your code. Here is how I would re-write your code:
app.post("/login", (req, res, next) => {
users.find({email:"xyz#gmail.com"})
.then(docs => {
console.log(docs);
res.json(docs);
})
.catch(e => {
console.log(e);
next(e);
})
})

How to join 2 collections in mongoose using nodejs

I want to join two collection using mongoose nodejs but i am stuck,
collection1
collection2
const mongoose = require('mongoose');
const gameSchema = new mongoose.Schema({
providerName:{
type: String
},
gamesSettings :[{
type: mongoose.Schema.Types.ObjectId,
ref: 'games_setting'
}]
});
module.exports = mongoose.model('gamesDetails', gameSchema);
This is the route :
router.get('/', async (req, res)=>{
try {
const gamesDetails1 = await joinCollection.find();
res.json(gamesDetails1);
//res.render('./games/gamesetting', { data: gamesDetails1 });
} catch (e) {
res.json({ message: e });
}
});
I am getting null in response.
I'm not sure that I understood your question correctly but I'm thinking that what you need is to execute a query where you get gameeSetting populated. The answer to that would be:
const details = await gamesDetails.find().populate('gamesSettings');

how to insert data in multiple mongodb collections using mongoose & node.js

i am new in node.js. I'm trying to store three different objects in collection in mongodb using node.js.
index.js
var mongoose = require('mongoose');
var bodyparser = require('body-parser');
var app = express();
var control = require('./controllers/controller');
var port = 3200;
mongoose.connect(
'mongodb://localhost:27017/create-company',
{useNewUrlParser: true},
err => {
if(err) throw err;
console.log('connection successfully');
}
)
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({extended: true}));
app.use('/api', control);
app.listen(port, function(){
console.log('start your server on: ', port);
});
model.js
var mongoose = require('mongoose');
var CompanySchema = new mongoose.Schema({
companyname: String,
founder: String,
contact: String,
location: String
});
var company = mongoose.model("company", CompanySchema);
var BranchSchema = new mongoose.Schema({
branchname: String,
branchmanger: String,
contact: String,
location: String
});
var branch = mongoose.model('branch', BranchSchema);
var UserSchema = new mongoose.Schema({[enter image description here][1]
username: String,
userrole: String,
age: Number
});
var user = mongoose.model('user', UserSchema);
module.exports = {
company: company,
branch: branch,
user: user
}
controller.js
var express = require('express');
var router = express.Router();
var company = require('../models/model');
router.post('/create_company', function (req, res) {
var new_company = new company.company(req.body);
var new_branch = new company.branch(req.body);
var new_user = new company.user(req.body);
new_company.save(function (err, data) {
if (err)
res.send(data);
console.log(data);
});
new_branch.save(function (err, data) {
if (err)
res.send(data);
console.log(data);
});
new_user.save(function (err, data) {
if (err)
res.send(data);
console.log(data);
});
});
i am pass data to postman like this:
[{
"companyname": "stack",
"founder": "alex",
"contact": "1234567890",
"location": "in"
},
{
"branchname": "am",
"branchmanager": "abc",
"contact": "8754216523",
"location": "inn"
},
{
"username": "xyz",
"userrole": "admin",
"age": "23"
}]
enter image description here
There are three problems here:
You are attempting to create a new document by passing the entire body to the constructor. You need to pass the correct array element to it's respective constructor.
var new_company = new company.company(req.body[0]);
var new_branch = new company.branch(req.body[1]);
var new_user = new company.user(req.body[2]);
You are attempting to send a response more than once. You need to coordinate the callbacks so that you send the response after they all have completed. I suggest you use promises to accomplish this, fortunately Mongoose supports promises.
Promise.all([
new_company.save(),
new_branch.save(),
new_user.save()
]).then(function (data) {
res.send(data);
console.log(data);
});
You are not handling the error correctly. Your if (err) statement will cause res.send(data) to be called when there is an error, this is certainly not desired. Using the promise based method defined above error handling is very simple.
Promise.all([
new_company.save(),
new_branch.save(),
new_user.save()
]).then(function (data) {
res.send(data);
console.log(data);
}).catch(function (err) {
res.status(400).send('Uh oh! Something bad happened.');
console.error(err);
});
If you use ES6 syntax you can write a synchronous looking route, which may be more familiar if you are coming from a different language:
router.post('/create_company', async (req, res) => {
try {
const [company, branch, user] = req.body;
const data = await Promise.all([
new company.company(company).save(),
new company.branch(branch).save(),
new company.user(user).save()
]);
res.send(data);
} catch (err) {
res.status(400).send('Uh oh! Something bad happened.');
console.error(err);
}
});

Mongoose: find statement not executing

This router get function is entered, the log statement is printed to the console, but the find statement doesn't seem to be executing. Any obvious reasons?
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const Product = require('../models/product');
module.exports = router;
const url = "mongodb://xxxx#ds027425.mlab.com:xxxx/xxxx";
mongoose.Promise = global.Promise;
mongoose.createConnection(url, function(err) {
if(err) {
console.log('Error!!!' + err);
} else {
console.log('Connected to Database!');
}
});
router.get('/product/specialvalue', function(req, res) {
console.log('Get specialvalue called xxxx');
Product.find({'special_value': true})
.sort({'price': 1})
.exec(function(err, products) {
if(err) {
console.error('Error retrieving special value products!');
res.json(err);
} else {
console.log("products = " + JSON.stringify(products));
res.json(products);
}
});
});
This is the Mongoose Model:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ProductSchema = new Schema({
producttype: String,
name: String,
brand: String,
model: String,
price: Number,
list_price: Number,
description: String,
rating: Number,
Continuation of the model: (The system is compelling me to add more detail)
item_no: String,
special_value: Boolean,
warranty: String,
feature: [String],
image: [String],
Continuation of the model:
specification: {
lowes_exclusive : Boolean,
color : String,
high_efficiency : Boolean,
automatic_load_balancing : Boolean,
product_capacity : String,
large_items_cycle : Boolean,
Continuation of the model:
exclusive_cycle : String,
maximum_spin_speed : String,
water_levels : String,
number_of_rinse_cycles : String
}
});
Continuation of the model:
var Product = mongoose.model('Product', ProductSchema, 'product');
module.exports=Product;
Your issue is with how you are connecting the the database. mongoose.createConnection() returns a connection object to the database, but it does not set it to be mongoose's default connection. The reason why the find query is not executing is because Mongoose queues all the DB calls and waits for there to be an open connection before it processes them, instead of throwing an error when there is no connection. Using mongoose.connect() will solve your problem. You can read about it here http://mongoosejs.com/docs/api.html#index_Mongoose-connect
There are some differences when you use .createConnection instead of .connect.
Here's the refactored code that works:
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const url = "mongodb://xxxx#ds027425.mlab.com:xxxx/xxxx";
const Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
const db = mongoose.createConnection(url, function(err) {
if(err) {
console.log('Error!!!' + err);
} else {
console.log('Connected to Database!');
}
});
const ProductSchema = new Schema({
producttype: String,
name: String,
brand: String,
model: String,
...
}
});
const Product = db.model('Product', ProductSchema);
router.get('/product/specialvalue', function(req, res) {
console.log('Get specialvalue called xxxx');
Product.find({'special_value': true})
.sort({'price': 1})
.exec(function(err, products) {
if(err) {
console.error('Error retrieving special value products!');
res.json(err);
} else {
console.log("products = " + JSON.stringify(products));
res.json(products);
}
});
});
Check out this post for a very good explanation on how to use .createConnection

Express node.js with mongoose CRUD strange behavior.

I'm starting my adventure with NodeJS. I've choose express web framework with mongoose database. As part of my front-end I'm using AngularJS.
First the front end, basic form args passing to /api/user.
$scope.form = {};
$scope.submitUser = function () {
console.log($scope.form);
$http.post('/api/user', $scope.form).
success(function(data) {})
.error(function(data) {});
};
$scope.form equals to:
Object {name: "foo", surname: "bar", email: "foobar#bar.foo"}
Then we got the back-end, where I start with default user schema:
var userSchema = new mongoose.Schema({
name : String,
surname : String,
email : String
});
var User = mongoose.model('User', userSchema);
And the api post handler:
app.post('/api/user', function (req, res) {
User.create({
name : req.name,
surname : req.surname,
done : false
}, function(err, user) {
if (err)
res.send(err);
res.json(user);
});
});
And the result of that instead of object is just id with __v:
__v: 0
_id: "536e218351b1182d0f000001"
PS. This one is magic, I have completly no idea why this is happening:
Those records above __v and _id, are not being save anywhere (show collections, and find() on each of those results in null). But when I run
User.find(function(err, users) {
if (err)
res.send(err)
res.json(users);
I get few records (previous tries of passing this form) with it's __v and _id.
Connection looks like this:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:1/test');
Thanks for any tips, explanation to that. Sorry for my lack of knowledge but I really tried.
Have a nice day! ;)
Assuming that you send the json object in the body (payload) of POST from client, The server should access the value as req.body.name, not req.name
app.post('/api/user', function (req, res) {
User.create({
name : req.body.name,
surname : req.body.surname,
done : false
}, function(err, user) {
if (err)
res.send(err);
res.json(user);
});
});
Make sure you pass body-parser middleware to express:
var express = require('express')
var app = express()
app.use(express.bodyParser()); // for express 3.x
or for express 4.x
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
app.use(bodyParser()); // for express 4.x
In my case it does not work. Why?
I am getting the value from req.body.name
If I log it console.log(req.body.name); I get the value on my console.
POST:
{ name: 'typing any name', status: null }
typing any name
So the workflow between my frontend (angular.js), the form and the backend (node.js, express, mongoose) seems to work. Now I POST the value, but I get an empty object in my mongoDB.
{"_id":"543a50a974de6e2606bd8478","__v":0}
app.post('/api/offers', function (req, res){
var offer;
console.log("POST: ");
console.log(req.body);
console.log(req.body.name);
offer = new OfferModel({
name: req.body.name,
value: req.body.value,
title: req.body.title,
content: req.body.content,
});
offer.save(function (err) {
if (!err) {
return console.log("created offer" + req.body.name);
} else {
return console.log(err);
}
});
return res.send(offer);
});
And here is the model:
var offerSchema = mongoose.Schema({
offer : {
name : String,
value : String,
title : String,
content : String,
image : String,
start : String,
end : String,
targets : String,
beacons : String,
published : String
}
});
var OfferModel = mongoose.model('Offer', offerSchema);

Resources