I'm using Mongodb and Nodejs.
I have two collections projects and users.
I want to retrieve name in the login collection based on the memberId i will give in the Project collection.I tried the code below, its populating as null.
My question is how to give values to memberId in projectModel in the frontEnd.Beacause it is of type of objectId.I want to pass value to memberId as "sam#gmail.com". Based on this, i want retrieve name from user schema.
Heremy schema :
UserSchema
'use strict';
var mongoose = require('mongoose'),
bcrypt = require('bcryptjs'),
crypto = require('../lib/crypto');
var userModel = function () {
var userSchema = mongoose.Schema({
name: String,
login: { type: String, unique: true }, //Ensure logins are unique.
password: String,
role: String
});
userSchema.pre('save', function (next) {
var user = this;
if (!user.isModified('password')) {
next();
return;
}
next();
});
userSchema.methods.passwordMatches = function (plainText) {
var user = this;
return bcrypt.compareSync(plainText, user.password);
};
return mongoose.model('User', userSchema);
};
ProjectSchema
'use strict';
var mongoose = require('mongoose'),
schema = mongoose.Schema;
var projectModel = function () {
var projectSchema = schema({
projectName: String,
projectNo: String,
startDate: String,
endDate: String,
releases:String,
sprintDuration:String,
sprintCount:String,
teamname: String,
teamno: String,
memberId :
{type: schema.Types.ObjectId, ref: 'users'},
story: [{
name: String,
creator: String,
date: String,
desc:String,
teamMember:String,
sprintNo: String,
sprintStartDate: String,
sprintEndDate: String,
status: String
}]
});
module.exports = new projectModel();
router.post('/home', function (req, res) {
var projectName = req.body.projectName && req.body.projectName.trim();
var projectNo = req.body.projectNo && req.body.projectNo.trim();
var memberId = req.body.memberId;
Project.
find({})
.populate('memberId')
.exec(function(err, people) {
if (err) return handleError(err);
console.log( people);
});
Related
I'm trying a to make a post request to save new data to one of my subdocuments, but I'm getting an error when trying to access the subdocument in the function. It keeps coming back as undefined. How can I get a specific user by id and create and add new data the one it's subdocuments?
model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const ClassworkSchema = new Schema({
name: String,
time: Date,
todo: String,
isDone: false
});
const OutcomesSchema = new Schema({
name: String,
time: Date,
todo: String,
isDone: false,
isApproved: false
})
const MeetupSchema = new Schema({
name: String,
time: Date,
location: String,
attended: false
})
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
classwork:{type: [ClassworkSchema], default: []},
outcomes: [OutcomesSchema],
meetups: [MeetupSchema],
});
module.exports = User = mongoose.model('users', UserSchema);
controller
classworkRouter.post("/:userId/", (req, res) => {
User.findById(req.params.user_id, (err, user) => {
if (err) return err;
new_classwork = new classwork();
(new_classwork.name = req.body.name),
(new_classwork.date = req.body.date),
(new_classwork.todo = req.body.todo),
(new_classwork.isDone = req.body.isDone);
console.log(new_classwork);
user.classwork = {};
user.classwork.name = req.body.classwork.name;
user.classwork.todo = user.classwork.todo;
if (user.classwork === undefined) {
user.classwork.push(new_classwork);
} else {
user.classwork = [new_classwork];
}
user.save(function (err, data) {
if (err) res.send(err);
res.json({ message: "work added", data: data });
});
});
});
you can see the error in the terminal in the following phto:
in this part of code
new_classwork = new classwork()
you shoud defined the new_classwrok like this :
let new_classwork = new classwork()
and new classwork() is not defined, you must to require Model of classwork in controller..
in schema file export schemas like this :
const User = mongoose.model('users', UserSchema);
const Classwork = mongoose.model('Classwork', ClassworkSchema );
module.exports = {
User : User ,
Classwork : Classwork
}
in controller.js
const {User} = require('../models/certification');
const {Classwork } = require('../models/certification');
after require models you can use new Crosswork like this :
note: Classwork with uppercase character
let new_classwork = new Classwork()
I have this part of code in my controller, what I want to do is when I do a "getProject" in postman "localhost:3000/project/:id" in the same screen do a post or a put over it with the params, but when I tried to do the put or post it doesn't save in my project model
I tried with this code but doesn't do that I want
function createWork(req, res) {
var work = new Work();
var project = new Project();
var projectId = req.params.id;
var params = req.body;
obra.name = params.name;
obra.oficialName = params.oficialName;
obra.price = params.price;
obra.workType= params.workType;
obra.ubication = params.ubication;
console.log(params);
Project.update({"Title":"project"}, {
$push: {
"work": {
"name":'name',
"oficialName":'oficialName',
"price":'price',
"workType":'workType',
"ubication":'ubication',
}
}
},
{safe: true, upsert: true},
function(err, updProject){
if (err) {
res.status(404).send({message: 'Error'});
} else {
res.status(200).send({project: updProject});
}
});
}
I have two models, the firstone is "project"
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Work = require('../models/work');
var ProjectsSchema = Schema({
name: String,
officialName: String,
price: String,
startDate: String,
endDate: String,
contract: String,
works: [{ type: Schema.Types.Object, ref: 'Work'}]
});
var Project = mongoose.model('Project', ProjectsSchema);
and the second is "work" model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var WorksSchema = Schema({
name: String,
officialName: String,
price: String,
workType: String,
ubication: String
});
module.exports = mongoose.model('Work', WorksSchema);
and I want to do a function in project controller that create and push the "work" data into existing "project"
Controller.js
function createWork(req, res) {
var newProject = new Project();
var name = req.body.name;
var oficialName = req.body.oficialName;
var price = req.body.price;
var workType= req.body.workType;
var ubication = req.body.ubication;
var dataToPush = {
name : name,
officialName : officialName,
price : price,
workType : workType,
ubication : ubication
}
newProject.update({"Title":"project"}, {
$push: {
"work": dataToPush
}
},
{new : truesafe, safe : true, upsert : true},
function(err, updProject){
if (err) {
res.status(404).send({message: 'Error'});
} else {
res.status(200).send({project: updProject});
}
});
}
Model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var WorkSchema = new mongoose.Schema({
name : String,
officialName : String,
price : String,
workType : String,
ubication : String
},{timestamps:true})
var ProjectSchema = new mongoose.Schema({
projectName : String,
work : [WorkSchema]
},{timestamps:true});
module.exports = mongoose.model('project', ProjectSchema)
I do that I want, with this code as my controller
function createWork(req, res) {
Project.findByIdAndUpdate((req.params.id), {
$push: {
"works": req.body
}
},
function(err, updProject) {
if (err) {
res.status(404).send({message: 'Error'});
} else {
res.status(200).send({project: updProject});
}
});
}
and with this as my model
'use strict'
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var WorkSchema = new mongoose.Schema({
name: String,
officialName: String,
price: String,
workType: String,
ubication: String
},{timestamps:true});
var ProjectsSchema = new mongoose.Schema({
name: String,
officialName: String,
price: String,
contract: String,
start: String,
end: String,
works: [WorkSchema]
},{timestamps:true});
module.exports = mongoose.model('Project', ProjectsSchema);
I want to find and update only one object in my array of object, that I try to findAndUpdate:
So I want to find my document with correct name and password, and then find only one subdocument, that I want update/save into
logic:
roomModel.findOneAndUpdate({ $and: [{ name: req.body.roomName }, { password: req.body.roomPassword }], 'users.name': req.body.userName }, {
'$set': {
'users.$.latitude': req.body.latitude,
'users.$.longitude': req.body.longitude,
'users.$.updateDate': new Date()
}
})
.then((room) => {
// ...
})
roomModel:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = require('./user').userSchema;
var room = new Schema({
name: String,
password: String,
users: [userSchema]
});
module.exports.roomSchema = room;
module.exports.roomModel = mongoose.model('room', room);
userModel:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var user = new Schema({
name: String,
latitude: String,
longitude: String,
updateTime: Date
});
module.exports.userSchema = user;
module.exports.userModel = mongoose.model('user', user);
I don't exactly know how to perform that and search along with subdocument search
can you explain me how to organize mongoose models to create one to many connections? It is needed keep separate collections.
suppose i have stores and items
//store.js
var mongoose = require('mongoose');
module.exports = mongoose.model('Store', {
name : String,
itemsinstore: [ String]
});
//item.js
var mongoose = require('mongoose');
module.exports = mongoose.model('Item', {
name : String,
storeforitem: [String]
});
Am i doing it in the right way?
And how to access pass data to arryas?
Here is the code yo enter name to item. But how to enter id to array of id's (itemsinstore)?
app.post('/api/stores', function(req, res) {
Store.create({
name: req.body.name,
}, function(err, store) {
if (err)
res.send(err);
});
})
You should use model reference and populate() method:
http://mongoosejs.com/docs/populate.html
Define your models:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var storeSchema = Schema({
name : String,
itemsInStore: [{ type: Schema.Types.ObjectId, ref: 'Item' }]
});
var Store = mongoose.model('Store', storeSchema);
var itemSchema = Schema({
name : String,
storeForItem: [{ type: Schema.Types.ObjectId, ref: 'Store' }]
});
var Item = mongoose.model('Item', itemSchema);
Save a new item into an existing store:
var item = new Item({name: 'Foo'});
item.save(function(err) {
store.itemsInStore.push(item);
store.save(function(err) {
// todo
});
});
Get items from a store
Store
.find({}) // all
.populate('itemsInStore')
.exec(function (err, stores) {
if (err) return handleError(err);
// Stores with items
});
You can do using the best practices with Virtuals.
Store.js
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const StoreSchema = new Schema({
name: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
}
})
StoreSchema.virtual('items', {
ref: 'Item',
localField: '_id',
foreignField: 'storeId',
justOne: false // set true for one-to-one relationship
})
module.exports = mongoose.model('Store', StoreSchema)
Item.js
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const ItemSchema = new Schema({
storeId: {
type: Schema.Types.ObjectId,
required: true
},
name: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
}
})
module.exports = mongoose.model('Item', ItemSchema)
StoreController.js
const Store = require('Store.js')
module.exports.getStore = (req, res) => {
const query = Store.findById(req.params.id).populate('items')
query.exec((err, store) => {
return res.status(200).json({ store, items: store.items })
})
}
Keep in mind that virtuals are not included in toJSON() output by default. If you want populate virtuals to show up when using functions that rely on JSON.stringify(), like Express' res.json() function, set the virtuals: true option on your schema's toJSON options.
// Set `virtuals: true` so `res.json()` works
const StoreSchema = new Schema({
name: String
}, { toJSON: { virtuals: true } });
Okay, this is how you define a dependancy:
var mongoose = require('mongoose');
module.exports = mongoose.model('Todo', {
name : String,
itemsinstore: [{ type: Schema.Types.ObjectId, ref: 'Item' }]
});
And make sure you have different names:
var mongoose = require('mongoose');
module.exports = mongoose.model('Item', {
name : String,
storeforitem: [String]
});
Keep an eye on Item in both cases.
And then you just want to pass the array of ObjectIDs in it. See more here: http://mongoosejs.com/docs/populate.html
Try this:
Store.findOne({_id:'5892b603986f7a419c1add07'})
.exec (function(err, store){
if(err) return res.send(err);
var item = new Item({name: 'Foo'});
item.save(function(err) {
store.itemsInStore.push(item);
store.save(function(err) {
// todo
});
});
I'm new to node.js and I am having problem accessing to the when multiple mongoose schema were declare.
//schema.js in model
var mongoose = require('mongoose');
var Schema = mongoose.Schema
, ObjectId = Schema.ObjectId;
//User Schema
var userSchema = new Schema({
id: ObjectId,
firstname: {type: String, require: true},
lastname: {type: String, require: true},
username: {type: String, unique: true, require: true},
password: {type: String, require: true},
role: {type: [String], require: true}
})
var User = mongoose.model('User', userSchema);
module.exports = User;
//Question Schema
var qnSchema = new Schema({
id: ObjectId,
question: {type: String, require: true},
module_id: {type: ObjectId, ref: 'Module'}
})
var Question = mongoose.model('Question', qnSchema);
module.exports = Question;
//Answer Schema
var ansSchema = new Schema({
id: ObjectId,
answer: String,
question: {type: ObjectId, ref: 'Question'}
})
var Answer = mongoose.model('Answer', ansSchema);
module.exports = Answer;
//Module Schema
var modSchema = new Schema({
id: ObjectId,
name: {type: String, require: true}
})
var Module = mongoose.model('Module', modSchema);
module.exports = Module;
//Role Schema
var roleSchema = new Schema({
id: ObjectId,
role: {type: String, require: true}
})
var Role = mongoose.model('Role', roleSchema);
module.exports = Role;
//index.js in controller
var mongoose = require('mongoose');
var User = require('../models/schema');
var db = mongoose.connect('mongodb://localhost/damai');
module.exports = function(app) {
app.get('/', function(req, res) {
if (typeof req.session.userid == 'undefined') {
res.render('login', { title: app.get('title') });
} else {
res.render('index', { title: app.get('title') });
}
});
app.post('/login', function(req, res) {
passwordVerification(req, res);
});
}
function passwordVerification(req, res)
{
var userid = req.param('userid');
var password = req.param('password');
User.findOne({'username': userid},{'password': 1}, function(err, cb)
{
console.log(cb);
if(cb!= null)
{
if (password == cb.password) {
req.session.userid = userid;
res.render('index', { title: app.get('title'), 'userid': userid });
} else {
res.render('login', { title: app.get('title'), error: 'Invalid login'});
}
}
else
{
res.render('login', { title: app.get('title'), error: 'Invalid login'});
}
});
}
When I only have the "User Schema" in my schema.js, the database call from method "passwordVerification()" from index.js will return me the relevant password that was retrieve from the database. However, when I start adding in other schema such as "Question Schema" in schema.js, the method "passwordVerification()" will always return null.
When exporting multiple models from a single file like you are in schema.js, you need to give each exported model its own exports field name.
For example, replace the multiple module.exports = ... lines in schema.js with this code at the end of the file that exports all models:
module.exports = {
User: User,
Question: Question,
Answer: Answer,
Module: Module,
Role: Role
};
And then in index.js you can access the models like so:
var models = require('./schema');
...
models.User.findOne(...