How to catch a mongodb error from mongoose? - node.js

when there is a violation of the {unique: true} schema definition in mongoose- there is an E11000 error from MongoDB and not from mongoose.
when I use schema.save(err) - mongoose does not catch this error.
any ideas how to catch it from node.js?
here is a code excerpt:
var Plan = new Schema({
slug: {type : String, default : '', trim : true, unique: true, required: true},
title: {type : String, default : '', trim : true},
body: {type : String, default : '', trim : true},
createdAt : {type : Date, default : Date.now}
})
....
// create new test records
var planArray = [
{slug: 'test', title: 'A', body: 'Lorem ipsum'},
{slug: 'test', title: 'B', body: 'Lorem ipsum'},
{slug: 'another_test', title: 'C', body: 'Lorem ipsum'}
]
var arrayLength = planArray.length;
for (var i = 0; i < arrayLength; i++) {
var p = new Plan(planArray[i])
p.save(function(err, saved){
if (err)
{console.log("error creating fixture " + err)}
})
}

Related

not able to save document with ref mongoose

I can't save my insert
MY MODELS :
Action and Type_intervention
var mongoose = require("mongoose"),
Schema = mongoose.Schema;
var actionSchema = new Schema({
action: {
type: String,
required: true,
unique: true
},
}); //Exporter le model
module.exports = mongoose.model('Action', actionSchema);
/*-----------------------------------------*/
var mongoose = require("mongoose"),
Schema = mongoose.Schema;
var type_interventionSchema = new Schema({
type_name_intervention : {type : String},
libelle : {type : String},
Standart : {type : String},
libelle_crt : {type : String},
action : {type: Schema.ObjectId, ref: 'Action'},
});
//Exporter le model
module.exports = mongoose.model('Type_intervention',type_interventionSchema);
/*--------------------------------------*/
MY CONTROLLER:
var new_type_intervention = new Type_intervention({
type_name_intervention: req.body.type_name_intervention,
libelle: req.body.libelle,
Standart: req.body.Standart,
libelle_crt: req.body.libelle_crt,
action: req.body.action,
})
new_type_intervention.save((err, newinter) => {
if (err) {
return res.send({
message: 'Error when try to save',
'intervention': new_type_intervention,
'req.action': req.body.action,
'new_type_intervention_action': new_type_intervention.action
});
}
return res.send({
message: 'Add with succes',
'intervention': new_type_intervention
})
})
POSTMAN RUN : The error is catched (new_intervention.action not apear and there type is undefined !? )
I think this is a probleme
{ "type_name_intervention":"f",
"libelle":"f",
"Standart":"f",
"libelle_crt":"f",
"action":"test"}
//Results:
{
"message": "Error when try to save",
"intervention": {
"type_name_intervention": "f",
"libelle": "f",
"Standart": "f",
"libelle_crt": "f",
"_id": "591eb2ccd4325d0e40b2d038"
},
"req.body.action": "test",
"type of new_type_intervention_action": "undefined"
}
I found the solution :
Before save : i try to find the action_id
Action.findOne({
'action': req.body.action,
})
.exec(function (err, found_action) {
if (found_action) {
new_type_intervention.action=found_action._id; // This is GOOD practice
new_type_intervention.save();
return res.send({
'type': typeof req.body.action,
message: 'type intervention ajoutee avec succes '
})
}
})

MongoDB join two collections using aggregation $lookup or populate in Node.js

Here are two collections' schema
var activitySchema = new Schema({
activity_id: {type: String, index: {unique: true}, required: true},
begin_date : String,
...
})
var registrationSchema = new Schema({
activity_id: {type: String, index: {unique: true}, required: true},
registration_id: {type:String, trim: true, index: true ,required: true },
email : String,
...
})
I want activity.begin_date , registration.id , registration.email in the same query. How can I do? I've found some solutions on the internet, but still don't know whether using populate or aggregation $lookup (this one seems new).
Here's how I tried, but not working at all.
models.Registration.aggregate([
{
$lookup: {
from: "Activity",
localField: "activity_id",
foreignField: "activity_id",
as: "activity_docs"
}
},
{"$unwind" : "activity_docs"},
], function( err , result ){
if(result){
fullDoc = result;
}else{
next( err );
}
})
activity_id should be ObjectId data type. ObjectId documentation
If you want to use pupoluate, you must to use ref to the other schema.
Population documentation
var activitySchema = new Schema({
begin_date : String,
...
})
var Activity= mongoose.model('Activity', activitySchema );
var registrationSchema = new Schema({
activity_id: {type: Schema.Types.ObjectId, ref : 'Activity', required: true},
email : String,
...
})
var Registration = mongoose.model('Registration', registrationSchema);
So the query such as :
var query = Registration.find({_id: 'registration_id parameter'});
query.select('_id activity_id email');
query.populate('activity_id','_id begin_date');
query.exec(function(error,result){
if(error){
/// handle error
}else{
// handle result
}
});

Mongoose + Expressjs - E11000 duplicate key error index?

I don't understand why I got this error below after adding the first entry:
E11000 duplicate key error index: mydb.datasets.$id_1 dup key: { : null }
I don't have any null value in my first entry:
{
"index" : "9IPZMW7IL",
"name" : "Tweets",
"owner_name" : "xxx",
"read_key" : "fb6f9125f4ca15c33fea89416c3351d1",
"write_key" : "d8a6c7e5fc73b5a91aa7a533565ed1f1",
"data" : {
"var1" : {
"name" : "particles"
}
},
"_id" : ObjectId("57729dc20cb70952424cdbb4"),
"created_at" : ISODate("2016-06-28T15:54:42.576Z"),
"entries_number" : 0,
"public" : true,
"__v" : 0
}
Below is my code:
// CRUD API:
// POST/ Create new dataset request
router.post("/", helper.authenticate, function(req, res) {
// Used to set the dataset owner
var sessionUser = req.session.user.name;
// Get values from the post request
var name = req.body.name;
var isPublic = req.body.public != undefined ? true:false;
// Delete the values from the request body so that we only keep information about the variables
delete req.body.name;
delete req.body.public;
// This is so that we can loop through the object in reverse order
// We do that so that the fields are saved in the right order on the db
// (this way it will appear in the right order on the 'edit' view)
var propertiesList = [];
for (var property in req.body) {
if (req.body.hasOwnProperty(property)) {
propertiesList.push(property);
}
}
propertiesList.reverse();
var variablesFields = {};
for (var i in propertiesList) {
console.log(propertiesList[i])
variablesFields[propertiesList[i]] = {name:req.body[propertiesList[i]],
values: Array};
}
// Create dataset
Dataset.create({
index: helper.uniqueIndex(),
name: name,
owner_name: sessionUser,
read_key: hat(),
write_key: hat(),
public: isPublic,
data: variablesFields
}, function(err, dataset) {
if (err) {
console.log("Error creating the dataset: " + err);
req.session.error = "A problem occured when creating the dataset. Please try again.";
} else {
console.log("New dataset created with id: " + dataset._id);
req.session.success = "Dataset " + name + " created successfully.";
}
res.redirect("/index");
});
});
Error:
Error creating the dataset:
WriteError({"code":11000,"index":0,"errmsg":"E11000 duplicate key
error index: mydb.datasets.$id_1 dup key: { : null
}","op":{"index":"2IPZMWHGI","name":"PM
2","owner_name":"xxx","read_key":"fc31c152aa86070252c70c0304e4ca5c","write_key":"238110753c8762ce4a547fa02100a299","data":{"var1":{"name":"particles"}},"_id":"57729dcf0cb70952424cdbb5","created_at":"2016-06-28T15:54:55.459Z","entries_number":0,"public":true,"__v":0}})
Model:
var datasetSchema = new mongoose.Schema({
index: {type: String, required: true, index: {unique: true}},
name: {type: String, required: true},
owner_name: {type: String, required: true},
read_key: {type: String},
write_key: {type: String},
public: {type: Boolean, default: false},
data: {type: Object},
entries_number: {type: Number, default: 0},
created_at: {type: Date, default: Date.now},
last_entry_at: {type: Date}
});
Any idea why and how I can fix this?
I solved it by removing a "id" key that I initially declared as
id: { type: String, unique: true, required: true},
I removed this line and deleted the initial collection and that solved the issue.

Mongoose subdocument not created in mongoDB but added to parent array

I have a method to update the commerce information. There is the possibility to add Workdays to the commerce by sending them in the request body.
There following code works fine except that the workdays are not created in mongoDB. They are only saved in the Commerce document (as an array od ids) but the Collection called "workday" is not createdin mongoDB. Why it's not created?
if(req.body.workdays){
var workdays = req.body.workdays;
var lunch = req.body.lunch.split("_");
commerce.workdays=[];
for(var i =0, size=workdays.length; i<size; i++ ){
var item=new Workday();
item.dayOfWeek = workdays[i];
item.owner=commerce._id;
var range = new Range();
range.initial = lunch[0];
range.end = lunch[1];
range.workday = item;
item.ranges.push(range);
commerce.workdays.push(item);
}
}
commerce.save(function(err) {
if(!err) {
log.debug('Updated');
res.status(200).send(commerce);
} else {
errorHandler.processError(err, res, log);
}
});
here are the models:
var CommerceSchema = new Schema({
// Common fields.
createdAt : {type : Date, default : Date.now},
location: [Number, Number],
photos: [{type : Schema.Types.ObjectId, ref : 'Photo'}],
name: { type: String},
address: { type: String},
email: { type: String, default: "-"},
workdays: [{type : Schema.Types.ObjectId, ref : 'Workday'}],
description: { type: String, default: "-"},
phone: { type: Number},
user: {type : String, ref : 'User'},
type: [{ type: Number, default: 0}]
});
var WorkdaySchema = new Schema({
dayOfWeek: { type: Number},
owner: {type : String},
ranges: [{type : Schema.Types.ObjectId, ref : 'Range'}],
createdAt : {type : Date, default : Date.now}
});
var RangeSchema = new Schema({
initial: { type: Number},
end: { type: Number},
workday: {type : String, ref : 'Workday'}
});
"workdays" is expecting Mongo ObjectIds. You have to save the individual Workdays first, and then you can add their Ids (_id) to the workdays Array.

Node.js - Create Relationships with Mongoose from different file

I have two Schemas Products and Users in different files. Products are belong to User and User have many Product
The Problem is, I have try to use Populate but somehow it return not what I expected.
here is my Schema for Product on models products.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var users = require('../models/users');
var Product = mongoose.Schema({
user_id : {type: String, required: true },
category_id : {type: String, default: null},
title : {type: String, required: true },
content : {type: String, default : "" },
pictureUrls : Array,
counter : {type : Number, default : 0},,
lowercaseTitle : {type: String, default : null },
_user : { type: Schema.Types.ObjectId, ref: users.User }
});
Product.set('toObject', {
getters: true,
virtuals: true
});
module.exports = mongoose.model('Product', Product)
and this is my Schema for User on models users.js
var mongoose = require('mongoose');
var User = mongoose.Schema({
firstName : {type: String, default: "" },
lastName : {type: String, default: "" },
username : {type: String, required: true },
email : {type: String, required: true },
password : {type: String, default: "" },
bio : {type: String, default: "" },
website : {type: String, default: "" },
phone : {type: String, default: "" },
gender : {type: String, default: "" },
birthDate : {type: Date, default: null },
avatarUrl : {type: String, default: "" },
verified : {type : Boolean, default : false}
});
User.set('toObject', {
getters: true,
virtuals: true
});
module.exports = mongoose.model('User', User);
currently I am using method find by calling each Models
User.findOne({"sessionToken" : bearerHeader}, function (err, user){
Product.find({"user_id" : user._id}, function (err, products){
console.log(products);
});
});
but it takes time and became problem if there related to another models.
I'm calling populte with this
Product.findOne({}).populate('_user').exec(function(err, p){
console.log(p);
});
but attribute _user was not set and undefined
any help?
Thanks

Resources