object referencing/mongoose-mongodb - node.js

I have been taking colt Steeles's web development bootcamp classes,so i am on the associations topic. tried writing code to do a one to many association via object referencing, the code appears thus
var mongoose= require("mongoose");
mongoose.connect("mongodb://localhost/blogApp_demo_2",{useNewUrlParser:true});
var postSchema= new mongoose.Schema({
title:String,
content:String
});
var post= mongoose.model("post",postSchema);
var userSchema = new mongoose.Schema({
name: String,
Email:String,
posts:[
{
type:mongoose.Schema.Types.ObjectId,
ref:"post"
}]
});
var user= mongoose.model("user",userSchema);
post.create(
{
title:"beauty in the lilies",
content: "there is so much to marvel in lilies"
}, function(err,post){
user.findOne({email:"deleomoarukhe#yahoo.com"}, function(err,foundUser){
if(err){
console.log(err);
} else{
foundUser.posts.push(post);
foundUser.save(function(err,data){
if(err){
console.log(err);
}else{
console.log(data);
}
});
}
});
});
but on trying to execute this code it gives me this error
TypeError: Cannot read property 'posts' of null
tried everything i can to get this code running, to no avail.
p.s the code was to add a further comment to an already existing user.

Related

Can we Insert data in Object collection in Mongodb

Can anyone please help i tried to insert data in object, but not using array.
I need output like this
{"_id":{"$oid":"5bacbda18ffe1a2b4cb9b294"},
"type":{"name":"prudhvi",
"headings":["Abstract","Introduction","Models"]}}
but i am getting like this
{"_id":{"$oid":"5c52d7484c7644263cbc428a"},
"name":"prudhvi",
"headings":["Abstract","Introduction","Models"],
"__v":{"$numberInt":"0"}}
and I wrote my Collection like this
var articleTypeSchema = new mongoose.Schema({
type: { type: mongoose.Schema.Types.Object, ref: 'typeSchema' }
});
var typeSchema = {
name:String,
headings:[String],
};
var Collections = {
type: mongoose.model('article_types',typeSchema)
}
This is my backend what i wrote
userRouter.post('/addarticletype',(req,res)=>{
Collections.type.create({name:req.body.type,headings:req.body.head},function(err,result){
if (err) return res.status(500).send("There was a problem adding the information to the database");
else
res.status(200).send(result);
console.log(result);
})
})
In your model, change the data type to JSON instead of String and then when you are trying to create a new collection
var typeSchema = {
type:JSON,
};
Step 2: While creating collection, create a JSON object for that key.
userRouter.post('/addarticletype',(req,res)=>{
Collections.type.create({type:{name:req.body.type,headings:req.body.head}},function(err,result){
if (err)
return res.status(500).send("There was a problem adding the information to the database");
else
res.status(200).send(result);
console.log(result);
})
})
Step 3 : Done
You need to rewrite the model as below:
var typeSchema = new mongoose.Schema ({
name:String,
headings:[String],
});
var articleTypeSchema = new mongoose.Schema({
type: { type: mongoose.Schema.Types.Object, ref: 'typeSchema' }
});

saving to mongodb with mongoose fails but no error shown

Am creating a nodejs bookstore app. Books details which are strings/numbers/booleans are to be saved in MongoDB using mongoose while the book cover image is to be saved in an uploads folder in my root directory using multer.Here is my mongoose schema:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//Creating schema and model
var BookDataSchema = new Schema({
title: String,
author: String,
isbn: String,
price: Number,
quantity: Number,
availability: Boolean,
description: String
});
var BookData = mongoose.model('BookData', BookDataSchema);
module.exports = BookData;
This is the code to perform the saving function:
router.post('/', function (req, res) {
var newBook = new BookData({
title: req.body.bkname,
author: req.body.bkauthor,
isbn: req.body.bkisbn,
price: req.body.bkprice,
quantity: req.body.bkquant,
description: req.body.bkdesc
});
newBook.save(function (err) {
if (err) {
console.log(err);
} else {
console.log(newBook);
console.log('Book Details saved successfully');
}
});
}, function(req, res) {upload(req, res, (err) => {
if (err) {
console.log(err);
res.render('admin', {
msg: err
});
} else {
console.log(req.file);
return res.render('admin');
}});}
);
The main problem is when I console.log(newBook) or console.log(result) or check in mongo shell all I see is { _id: 5b4fdba80420890764ce13bf, __v: 0 }, only the id that mongodb creates is displayed which means the other data is not saved and worse it does not proceed to the other callback function. Am not getting any error apart from this warning:
(node:1220) [DEP0079] DeprecationWarning: Custom inspection function on Objects via .inspect() is deprecated
I tested the code for saving the image excluding that for saving the other data and it worked fine. Kindly help on what could be the problem and also advise me on how I would ensure the admin page is rendered only after everything has been saved. See the whole project in_this_git_repo

Error while Testing Create with Mocha,Chai, Node.JS and MongoSB

I am learning about testing with Mocha and setting up a few simple tests for an application. My first two test work but I keep getting an error for the last test.
The error message is : 2 passing (87ms)
1 failing
1) Routing Tests ## Create article should create a task:
Uncaught AssertionError: expected undefined to equal 'Test Title'
at Test. (test/todos.test.js:33:39)
at Test.assert (node_modules/supertest/lib/test.js:179:6)
at Server.assert (node_modules/supertest/lib/test.js:131:12)
at emitCloseNT (net.js:1646:8)
at _combinedTickCallback (internal/process/next_tick.js:135:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
Here is the error I am getting from the databse.
Validation is failing:{ ValidationError: Article validation failed:
title: Path title is required.
at ValidationError.inspect (/Users/patrickbentley/Desktop/Article-Scraper/node_modules/mongoose/lib/error/validation.js:57:23)
Here is my test:
describe('## Create article ', function() {
it('should create a task', function(done) {
request(app) .post('/saved') .send({"title":'Test Title'})
.end(function(err, res) {
expect(res.statusCode).to.equal(200);
expect(res.body.title).to.equal('Test Title');
task = res.body;
done();
});
});
});
Here is my Model:
// Require mongoose
var mongoose = require("mongoose");
// Create Schema class
var Schema = mongoose.Schema;
// Create article schema
var ArticleSchema = new Schema({
// title is a required string
title: {
type: String,
required: true
},
// link is a required string
link: {
type: String
},
// This only saves one note's ObjectId, ref refers to the Note model
note: {
type: Schema.Types.ObjectId,
ref: "Note"
}
});
// Create the Article model with the ArticleSchema
var Article = mongoose.model("Article", ArticleSchema);
// Export the model
module.exports = Article;
Here is my code for the '/saved' route:
router.post("/saved", function(req,res){
var entry = new Article(
{
title:req.body.title
});
entry.save(function(err, doc) {
// Log any errors
if (err) {
console.log(err);
}
// Or log the doc
else {
console.log(doc);
}
});
res.render('index');
});
So, I know that my format for the post action is wrong in my test, but I dont know what it is.

How to associate the ObjectId of the parent schema to the child schema in the same transaction?

I have two types of entities, users and families, with a many-to-one relationship between families and users, so one family can have many users but one user will only have one family. I attempted to create a Mongo schema that tries to achieve this relationship, but not sure if this is the right way to do it.
I have a button on my HTML page that when clicked, will generate a family code and also create a new family attribute for the family entity. However, I'm unable to connect that newly generated family.ObjectId to the user's familyid attribute in the user entity.
Any idea what I'm doing wrong?
My Models:
Family Model:
var mongoose = require("mongoose");
var shortid = require('shortid');
//Set Schema
var familySchema = mongoose.Schema({
individuals: [{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}],
familyCode: {
type: String,
'default': shortid.generate
}
});
//setup and export the model
module.exports = mongoose.model("Family", familySchema);
Users Model:
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = new mongoose.Schema({
username: String,
password: String,
image: String,
firstName: String,
lastName: String,
accountid: String,
isAdmin: {type: Boolean, default: false},
userlabel: String,
familyid:
{ type : mongoose.Schema.Types.ObjectId,
ref: "Family"}
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
My Route:
router.post("/familySetup", function(req, res){
if(!req.body.familyid){
var familyCode = shortid.generate();
console.log(familyCode);
// var individuals = {id:req.user._id}
var newFamily = {familyCode:familyCode};
Family.create(newFamily, function(err, newFamily){
if(err){
req.flash("error", "something seems to have gone amiss. Please try again.")
console.log(err);
res.redirect("home")
}else{
var updatedUser = {familyid:newFamily._id}
console.log(updatedUser);
User.findByIdAndUpdate(req.params.user_id, updatedUser, function(req, res){
if(err){
console.log(err);
}else{
//redirect to index
res.redirect("/familySetup");
}
});
}
});
}else{
alert("You already have a family account");
res.redirect("back");
}
});
Based on the error I get, I am able to create a familyCode and am able to create the variable, updatedUser. But it does not update the user with the new attribute. This is the error when I run the code:
ByJyRqb_Z
{ familyid: 59941dd6589f9a1c14a36550 }
events.js:141
throw er; // Unhandled 'error' event
^
TypeError: Cannot read property 'redirect' of null
at /home/ubuntu/workspace/mbswalay/routes/family.js:44:28
at Query.<anonymous> (/home/ubuntu/workspace/mbswalay/node_modules/mongoose/lib/model.js:3755:16)
at /home/ubuntu/workspace/mbswalay/node_modules/mongoose/node_modules/kareem/index.js:277:21
at /home/ubuntu/workspace/mbswalay/node_modules/mongoose/node_modules/kareem/index.js:131:16
at nextTickCallbackWith0Args (node.js:436:9)
at process._tickCallback (node.js:365:13)
It doesn't seem to be an error of mongodb, it's related to the route configuration, which seems make the response object to be null
User.updateOne(
{ _id: req.params.user_id },
{ $set: { familyid: newFamily._id } }
)
You have to set the value of an attribute using $set operator.

mongoose unique: true not work [duplicate]

This question already has answers here:
Unique index in mongoose not working
(1 answer)
Mongoose Unique index not working!
(35 answers)
Closed 8 years ago.
why mongoose unique not work at all in this script
var child_process = require('child_process');
// Load required packages
child_process.exec("mongo test --eval 'db.users.drop();'", function(err){
var mongoose = require('mongoose');
console.log(mongoose.version);
mongoose.connect('mongodb://localhost:27017/test');
// Define our user schema
var json = {};
json.phone = { type: String, required: true, unique: true};
var UserSchema = new mongoose.Schema(json);
var Model = mongoose.model('user', UserSchema);
var jp = new Model({ phone: "123456"});
mongoose.connection.on('open', function(){
console.log(jp);
jp.save(function(err){
console.log(err);
var jp2 = new Model({ phone: "123456"});
console.log(jp2);
jp2.save(function(err){
console.log(err);
process.exit();
});
})
});
});
I'm quite confused, the result is like
3.8.20
{ phone: '123456', _id: 54856cceb5b40f7a88fcc2af }
null
{ phone: '123456', _id: 54856cceb5b40f7a88fcc2b0 }
null
Thank you for your help.
This happens because you're saving the duplicated document before mongoose has finished creating the index. Mongoose creates the indexes on the go, after your app has started.
So, to ensure that your document will be saved only after the indexes were created, you have to listen to the index event of your model. For example:
Model.on('index', function (error) {
console.log(jp);
jp.save(function(err){
console.log(err);
var jp2 = new Model({ phone: "123456"});
console.log(jp2);
jp2.save(function(err){
console.log(err);
process.exit();
});
})
});
Now, when you try to save the second document (the duplicated one), your MongoDB will raise an error, because your save calls will just run after the indexes were created.

Resources