mongoose : insert data into an array of nested objects - javascript

I am working on a project using node.js mongodb. My schema somewhat looks like:
var Doctor = new Schema({
email : String,
password : String,
Dname : String,
blockAppoint:[{
day:String,
sslot:[Number],
eslot:[Number],
address:String,
status1:String
}]
});
If I take all these values as input from user, I can't figure out how to insert into the array of nested objects.
If my post api looks like:
var doc = new Doctor({
email : req.body.email,
password : req.body.password,
name : req.body.Dname,
blockAppoint:{
status1:req.body.xx,
day:req.body.day,
sslot:req.body.sslot,
eslot:req.body.eslot,
address:req.body.address
}
});
doc.save(function(err){
if(err){
res.send(err);
return;
}
res.json({
success: true,
message: 'doctor has been added!'
});
});
I'm able to input just one entry into the database. Does anyone know how do I change my api code so as to be able to take read input into my database.

Try adding the values to an array first using the push() method:
var sslot = [], eslot = [], blockAppoint = [];
sslot.push(req.body.sslot);
eslot.push(req.body.eslot);
blockAppoint.push({
status1: req.body.xx,
day: req.body.day,
sslot: sslot,
eslot: eslot,
address: req.body.address
});
var doc = new Doctor({
email: req.body.email,
password: req.body.password,
name: req.body.Dname,
blockAppoint: blockAppoint
});

Related

Cannot read the property of id undefined

I'm making a website where you can share campground photos. And when someone makes a comments I want only comment's owner to see delete and edit options.
I've made an model for comment and made an author object that includes comment's owner's id and username. But when I try to get the owner's ID from that author object it returns undefined also if I try to get data by find method and write Comment.author.id it returns syntax error and says Unexpected token "."
That's my comment model.
var commentSchema = new mongoose.Schema({
text: String,
author:{
username: String,
id: String,
}
});
That's the campground route
Campground.findById(req.params.id).populate("comments").exec(function(err, foundCampground){
if(err){
console.log(err);
}else{
//render show template with that campground
console.log(foundCampground.comments);
User.findById(req.user._id, (err, user)=>{
if(err){
console.log(err);
}else{
console.log(foundCampground.comments._id);
Comments.find({Comments.author.id: foundCampground.comments._id}, function(err, comment){
var authID = foundCampground.author.id;
var userID = user._id;
var commentID = comment.author.id;
console.log("Comment Id " + commentID);
console.log("UserID "+userID);
res.render("campgrounds/show",{campground: foundCampground, authID: authID, userID: userID});
});
}
});
}
});
Same thing worked for the campground model
var campgroundSchema = new mongoose.Schema({
name: String,
image: String,
description: String,
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
}],
author: {
id: String,
user: String,
}
});
I expect to get the user id from comment.author.id but I get undefined.
You may need to replace Comments.find({Comments.author.id: foundCampground.comments._id} with Comments.find({"author.id": foundCampground.comments._id}.

Update Array attribute using Mongoose

I am working on a MEAN stack application in which i defined a model using following schema:
var mappingSchema = new mongoose.Schema({
MainName: String,
Addr: String,
Mapping1: [Schema1],
Mappings2: [Schema2]
},
{collection : 'Mappings'}
);
I am displaying all this data on UI and Mapping1 & Mapping2 are displayed in the 2 tables where I can edit the values. What I am trying to do is once I update the values in table I should update them in database. I wrote put() api where I am getting these two updated mappings in the form of object but not able to update it in database. I tried using findAndModify() & findOneAndUpdate() but failed.
Here are the Schema1 & Schema2:
const Schema1 = new mongoose.Schema({
Name: String,
Variable: String
});
const Schema2 = new mongoose.Schema({
SName: String,
Provider: String
});
and my put api:
.put(function(req, res){
var query = {MainName: req.params.mainname};
var mapp = {Mapping1: req.params.mapping1, Mapping2: req.params.mapping2};
Mappings.findOneAndUpdate(
query,
{$set:mapp},
{},
function(err, object) {
if (err){
console.warn(err.message); // returns error if no matching object found
}else{
console.log(object);
}
});
});
Please suggest the best to way update those two arrays.
UPDATE :
I tried this
var mapp = {'Mapping2': req.params.mapping2};
Mappings.update( query ,
mapp ,
{ },
function (err, object) {
if (err || !object) {
console.log(err);
res.json({
status: 400,
message: "Unable to update" + err
});
} else {
return res.json(object);
}
});
what I got is
My array with size 3 is saved as String in Mapping2 array.
Please help. Stuck badly. :(
From Mongoose's documentation I believe there's no need to use $set. Just pass an object with the properties to update :
Mappings.findOneAndUpdate(
query,
mapp, // Object containing the keys to update
function(err, object) {...}
);

Node.js: How to get the incorrect fields in the Error object

I have unique and required fields in my schema below.
An error is returned when any of them are left blank.
How do I find the paths in Error object with information on which fields were left blank?
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
var Schema = mongoose.Schema;
var kullaniciShema = new Schema({
gsm: String,
email: String,
kullaniciAdi: { type: String, required: true, unique: true },
sifre: { type: String, required: true},
}, { collection: 'kullanici' });
kullaniciShema.plugin(uniqueValidator);
var Kullanici = mongoose.model('Kullanici', kullaniciShema);
module.exports = Kullanici;
Below is the controller where I save submitted data into the database. Some of the incoming data is empty, so I get an error for the fields that were left blank.
How do I find the incorrect fields in the Error object?
var yeniKullanici = new Kullanici({
gsm: req.body.gsm,
email: req.body.email,
kullaniciAdi: req.body.kullaniciAdi,
sifre: req.body.sifre,
});
yeniKullanici.save(function(err){
if (err) {
//var error=new err("hata");
//console.log(error.path);
selectAllFromKullanici((result) => {
//console.log(forUsersError.length);
forUsersError[forUsersError.length] = assert.equal(error.errors['ad'].message, 'Path `name` is required.');
res.render("kullanicilar", { kullanicilar: result, hata: forUsersError });
})
} else {
selectAllFromKullanici((result) => {
res.render("kullanicilar", { kullanicilar: result });
})
}
});
I'm sorry for my bad English.
I would check if the fields are empty BEFORE you try to run into a failure and extract data from an error message, which may fail on unknown errors.

Mongoose: Merging two documents that reference each other

I am currently trying to learn how to work with NoSQL, coming from a relational database background. In this project, I am using Express with Mongoose.
I am struggling with callbacks as I try to merge two models together, which reference each other. I am trying to edit each item in a group of one model (Ribbits) to contain the attributes of another (Users who posted a Ribbit). Because the call to find the User associated with a Ribbit is asynchronous, I am unable to return the collection of edited Ribbits (with user info).
In my website, I have ribbits (a.k.a. tweets) which belong to users. Users can have many ribbits. In one of my pages, I would like to list all of the ribbits on the service, and some information associated with the user who posted that ribbit.
One solution I found was embedded documents, but I discovered that this is, in my case, limited to showing ribbits which belong to a user. In my case, I want to start by getting all of the ribbits first, and then, for each ribbit, attach info about who posted that.
Ideally, I'd want my schema function to return an array of Ribbit objects, so that I can then render this in my view.
// models/user.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var userSchema = Schema({
username: String,
email: String,
password: String,
name: String,
profile: String,
ribbits: [{
type: Schema.Types.ObjectId,
ref: 'Ribbit',
}]
});
module.exports = mongoose.model('User', userSchema);
// models/ribbit.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
User = require('./user');
var ribbitSchema = Schema({
content: { type: String, maxlength: 140 },
created: { type: Date, default: Date.now() },
owner: { type: Schema.Types.ObjectId, ref: 'User' },
});
ribbitSchema.methods.getOwnerObj = function(cb) {
return User.findOne({ _id: this.owner }, cb);
}
ribbitSchema.statics.getAllRibbits = function(cb) {
this.find({}, function(err, ribbits) {
console.log('Before Transform');
console.log(ribbits);
ribbits.forEach(function(ribbit) {
ribbit.getOwnerObj(function(err, owner) {
ribbit = {
content: ribbit.content,
created: ribbit.created,
owner: {
username: owner.username,
email: owner.email,
name: owner.name,
profile: owner.profile,
}
};
});
});
});
}
module.exports = mongoose.model('Ribbit', ribbitSchema);
If I understand correctly, you can use Mongoose populate method for this scenario:
ribbitSchema.statics.getAllRibbits = function(cb) {
this.find({}).populate('owner').exec(function(err, ribbits){
console.log(ribbits[0].owner)
return cb(err, ribbits);
})
}

Difference between saved/load json object in Mongoose

I have a problem saving a json object in mongodb(Mongoose) so when i make the insert everything is ok, but when i make the request of the same object, Mongoose return a modified json. Its like Mongoose autocomplete the twitter field and i dont know why.
Here is my code:
UserSchema = mongoose.Schema({
firstName: String,
lastName: String,
email: String,
salt: String,
hash: String,
twitter:{
id: String,
email: String,
name: String
},
facebook:{
id: String,
email: String,
name: String,
username: String,
photo: String,
gender: String
}
});
I save json in my database:
User.create({
email : profile.emails[0].value,
facebook : {
id: profile.id,
email: profile.emails[0].value,
name: profile.displayName,
username: profile.username,
photo: profile.photos[0].value,
gender: profile.gender
}
}, function(err, user){
if(err) throw err;
// if (err) return done(err);
done(null, user);
});
But i when mongoose return a json.
Mongoose generated a field in the json. twitter:{} <----
I dont know why, can anyone lend me a hand?
If you look at the document saved to the MongoDB, you'll see that the twitter object isn't actually present unless the properties of the sub object are set. The object is created so that you can conveniently set properties without needing to worry about creating the sub/nested object. So you can do this:
var user = new User();
user.twitter.id = 'wiredprairie';
user.save();
Results:
{ "_id" : ObjectId("522259394eb9ed0c30000002"),
"twitter" : { "id" : "wiredprairie" }, "__v" : 0 }
And if you went one step further and wanted a more "pure" view of the data, you could use toJSON on the Mongoose model instance:
console.log(user.toJSON());
results:
{ _id: 522259ad3621834411000001, twitter: { id: 'wiredprairie' } }

Categories

Resources