reference and populate issue - node.js

[Solved - silly mistake in the model]
I have been trying to refer and populate in mongoose and expressjs, but its not working at all. I have followed these:
1. Mongoose examples
2. Mongoose populate
I created three files:
1) models/profile.js
var mongoose = require('mongoose'), Schema = mongoose.Schema, ObjectId = Schema.ObjectId;
var profileSchema = new Schema({
name: String
});
module.exports = mongoose.model('Profile', profileSchema);
2) models/work.js
var mongoose = require('mongoose'), Schema = mongoose.Schema, ObjectId = Schema.ObjectId;
var workSchema = new Schema({
title: String,
creditsFor: [{type: Schema.Types.ObjectId, ref: 'profile'}],
});
module.exports = mongoose.model('Work', workSchema);
3) controllers/work.js
var Work = require('../models/work.js'), fs = require('fs'), mongoose = require('mongoose');
......
exports.create = function(req, res) {
credits = [];
credits.push(mongoose.Types.ObjectId('5174a9ec993af25b01000003')); // I already created a 'Profile' and copy-pasted the _id
var work = {
title: req.body.title,
creditsFor: credits
}
var workObj = new Work(work);
workObj.save(function(err, data) {
if(err) {
throw err;
} else {
req.flash('info', 'Work item saved.');
res.redirect('/work/' + data._id);
}
});
}
.......
exports.show = function(req, res) {
var work = req.params.work;
Work.findOne({_id: work})
.populate('creditsFor')
.exec(function(err, data) {
if(err) {
throw err;
} else {
console.log(data);
res.render('site/work/show', {work: data, message: req.flash('info')});
}
});
}
When using populate(), returned creditsFor is null. When I comment populate(), it is a string(?), like this:
{
title: 'My Title',
creditsFor: '5174a9ec993af25b01000003'
}
Couldn't figure out whats going wrong. I tried to bring both the models in a single file, still nothing.

Related

Node.js: indexOf returning -1 even though item is in array

I want users to have the ability to click a button that pushes their username and id into an array associated with a collection in a database, but only if they're not already in that array.
My solution is:
var isInGroup = function(user, arr){
var match = arr.indexOf(user);
console.log(">>>>>>>" + match);
if(match === -1){
arr.push(user);
console.log("added user");
} else {
console.log("Already in group");
}
};
This works when I test it against example arrays in the console, but not when I'm querying the database. When I execute the function in my app, arr.indexOf = -1 even if the user is already in the array.
This is the relevant code:
Player.js
var express = require("express"),
router = express.Router({mergeParams:true}),
Game = require("../models/game"),
Player = require("../models/player"),
User = require("../models/user"),
middleware = require("../middleware");
//Add A Player
router.post("/", middleware.isLoggedIn, function(req, res){
//find game
Game.findById(req.body.game, function(err, foundGame){
console.log(">>>>" + foundGame);
if(err){
req.flash("error", "Something went wrong.");
} else {
//create player
Player.create(req.user, function(err, player){
if(err){
console.log(">>>> error" + player);
res.redirect("back");
} else {
player.id = req.user_id;
player.username = req.user.username;
middleware.isInGroup(player, foundGame.players);
foundGame.save();
res.redirect("back");
}
});
}
});
});
Game Schema
var mongoose = require("mongoose");
var gameSchema = new mongoose.Schema({
name:String,
author:{
id:{
type: mongoose.Schema.Types.ObjectId,
ref:"User"
},
username:String,
},
court:{
id:{
type:mongoose.Schema.Types.ObjectId,
ref:"Court"
},
name:String,
},
players:[
{
id:{ type:mongoose.Schema.Types.ObjectId,
ref:"Player",
},
username:String
}
],
time:{
start:String,
end:String
},
date:String,
});
module.exports = mongoose.model("Game", gameSchema)
Player Schema
var mongoose = require("mongoose");
var playerSchema = new mongoose.Schema({
id:{type:mongoose.Schema.Types.ObjectId,
ref:"User"
},
username: String
});
module.exports = mongoose.model("Player", playerSchema);
User Schema
var mongoose = require("mongoose"),
passportLocalMongoose = require("passport-local-mongoose");
var userSchema = new mongoose.Schema({
username: String,
password: String
});
userSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", userSchema);
As mentioned above, arr.indexOf(user) returns -1 even if user is already in the array. Why is this happening? Is there better solution to this problem? Thanks for the help. I've been banging my head for awhile on this one.

data is not insert in mongodb

I am beginner of nodejs and mongodb. I am inserting data to collection using mongoose ORM and model but not insert. Validation is working correct but data is not insert after filling complete data. I have not create collection in database manually. should I create collection manually in mongodb or create automatically when inserting document.
productsController
var mongoose = require('mongoose');
var db = require('../config/db_config');
var Product = require('../models/product');
//var Product = mongoose.model('Products');
var productController = {};
productController.add = function(req, res) {
var params = req.body;
if(!params) {
res.status(400).send({message: "Data can not be empty"});
}
var productData = new Product({
product_name : params.product_name,
price : params.price,
category : params.category
});
console.log(productData);
productData.save(function(err, product) {
if (err){
res.status(400).send({message:'Unable to save data! ' + err});
}else{
res.status(200).send({message:'Data has been saved! ' + product });
}
});
};
module.exports = productController;
Models code is here
var mongoose = require('mongoose');
var db = require('../config/db_config');
var Schema = mongoose.Schema;
var productSchema = new Schema({
product_name: { type: String, required: 'Product name cannot be left blank.' },
price: { type: String, required: 'Product price cannot be left blank.'},
category: { type: String , required: 'Product category cannot be left blank'},
updated_at : {type: Date, default: Date.now}
});
module.exports = mongoose.model('Products', productSchema);
routes file code is here:
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Product = require('../models/product.js');
var productsController = require('../controllers/productsController');
router.post('/add',productsController.add);
module.exports = router;
DB config file
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
var db = mongoose.createConnection('mongodb://localhost:27017/nodeweb', function(err,db){
if(err){
throw err;
console.log(err);
} else {
console.log('Successfully connected to database!');
}
});
module.exports = db;
I have insert controller, model and routes file code.
Please correct your method -
Controller function
exports.add = function(req, res) {
var new_product = new Products(req.body);
// you have define Products not Product
console.log(new_product);
new_product.save(function(err, product) {
console.log('add data');
if (err){
res.send(err);
}else{
res.json(product);
}
});
};
and for good practice in node js - i think you can start with express-app-generator
This Helps to make simple routing, with generic responses and in-built express middlewares with loggers.
I have resolved problem. database connection work with connect method.
mongoose.connect('mongodb://localhost:27017/nodeweb', {useMongoClient: true}, function(err,db){
if(err){
throw err;
console.log(err);
} else {
console.log('Successfully connected to database!');
}
});

Mongoose, can't print products from database

I have problem with print items in console.log or res.json from database.
what am I doing wrong
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test');
var Schema = mongoose.Schema;
var productSchema = new Schema({
title: String,
price: Number
});
var product = mongoose.model('product, productSchema');
mongoose.connect(db);
var db = 'mongodb://localhost/product';
router.get('/books', function(req, res) {
console.log('getting all products');
product.find({})
.exec(function(err, product) {
if (err) {
res.send('errror');
} else {
console.log(product);
res.json(product);
}
})
});
name of database products is : db.product
Thanks
Error:
C:\Users\Turqus\Desktop\node\products\node_modules\mongoose\lib\index.js:382
throw new mongoose.Error.MissingSchemaError(name);
^
MongooseError: Schema hasn't been registered for model "product, productSchema".
Use mongoose.model(name, schema)
at Mongoose.model (C:\Users\Turqus\Desktop\node\products\node_modules\mongoose\lib\index.js:382:13)
You have to make the Database Connection first.
change this
var product = mongoose.model('product, productSchema');
to
var product = mongoose.model('product', productSchema);
mongoose.model() accepts two parameter the name of the collection your model is for and the 2nd the Schema
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test');
var Schema = mongoose.Schema;
var productSchema = new Schema({
title: String,
price: Number
});
var product = mongoose.model('product', 'productSchema');
router.get('/books', function(req, res) {
console.log('getting all products');
product.find({})
.exec(function(err, product) {
if (err) {
res.send('errror');
} else {
console.log(product);
res.json(product);
}
})
});

express server api returns empty

i am trying to get the data from mongodb using express server but all i am getting is empty array => []
However if i run the db.Goserv.find() in console i get the results right please help
here is the server.js file
var Schema = mongoose.Schema;
var schema = new Schema({
type: String,
address: String,
servicecost: String
}, { collection: 'Goserv' });
var Goserv = mongoose.model('Goserv', schema );
module.exports = Goserv ;
app.get('/api/centre', function(req, res) {
Goserv.find(function(err, centre){
if(err){
res.send(err);
} else {
res.json(centre);
console.log(centre);
}
});
});
Try this...
var Schema = mongoose.Schema;
var schema = new Schema({
type: String,
address: String,
servicecost: String
}, { collection: 'Goserv' });
var Goserv = mongoose.model('Goserv', schema );
module.exports = Goserv ;
app.get('/api/centre', function(req, res) {
Goserv.find({},function(err, centre){
if(err){
res.send(err);
} else {
res.json(centre);
console.log(centre);
}
});
});

mongoose CastError: Cast to undefined failed for value "[object Object]" at path "apps"

I have a nested schema defined with mongoose:
//application.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Category = require('./category.js');
var Application = new Schema({
title : String,
cats : [Category]
});
Application.virtual('app_id').get(function() {
return this._id;
});
module.exports = mongoose.model('Application', Application);
and
//account.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var Application = require('./application.js');
var Account = new Schema({
username: String,
password: String,
apps: [Application]
});
Account.plugin(passportLocalMongoose);
module.exports = mongoose.model('Account', Account);
Now if I try to push to apps which is an array in account like this:
app.post('/application', function(req,res){
var name = req.user.username;
var newApp = new Application();
newApp.title = req.body.title;
console.log(newApp);
Account.findOneAndUpdate({username : name},
{$push: {apps: newApp}},
{safe: true, upsert: true},
function(err, model){
if (err){
console.log(model);
console.error("ERROR: ", err);
res.status(500).send(err);
}else{
res.status(200).send({"status":"ok"});
}
}
);
});
I get the error:
{ title: 'dogs', _id: 564f1d1444f30e0d13e84e7b, cats: [] }
undefined
ERROR: { [CastError: Cast to undefined failed for value "[object Object]" at path "apps"]
message: 'Cast to undefined failed for value "[object Object]" at path "apps"',
name: 'CastError',
type: undefined,
value: [{"title":"dogs","_id":"564f1d1444f30e0d13e84e7b","cats":[]}],
path: 'apps' }
what am I doing wrong?
EDIT:
Found the answer in this question
Practically I need to import the schema not the object
//account.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var ApplicationSchema = require('./application.js').schema; //<-- .schema was added
var Account = new Schema({
username: String,
password: String,
apps: [ApplicationSchema]
});
Account.plugin(passportLocalMongoose);
module.exports = mongoose.model('Account', Account);
To save the Application reference within the Account model's apps embedded document field, push the _id value in the Application model's callback on save:
account.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var Application = require('./application.js');
var Account = new Schema({
username: String,
password: String,
apps: [{type: Schema.Types.ObjectId, ref: 'Application'}]
});
Account.plugin(passportLocalMongoose);
module.exports = mongoose.model('Account', Account);
app.js
app.post('/application', function(req, res){
var name = req.user.username;
var newApp = new Application({
title: req.body.title
});
console.log(newApp);
newApp.save(function (err){
if (err) return handleError(err);
Account.findOne({ username: name }, function (err, doc){
if (err) return handleError(err);
doc.apps.push(newApp._id);
doc.save();
res.status(200).send({"status":"ok"});
});
});
});
Or using promises as:
const handleError = err => console.error(err);
app.post('/application', (req, res) => {
const name = req.user.username;
const newApp = new Application({
title: req.body.title
});
newApp.save().then(result => (
Account.findOneAndUpdate(
{ "username": name },
{ "$push": { "apps": result._id } }
)
)
.then(result => res.status(200).send({"status":"ok"}))
.catch(handleError);
});

Resources