NodeJS Mongoose - Cannot call method 'toString' of undefined - javascript

I am trying to print out to the console the name of a Team in my database, here is the code:
var Team = require('../schemas/Team').Model;
app.get('/match', function(req, res) {
var key = 1359407087999; // Team Key
Team.findByKey(key, function(err, team) {
util.log(team);
if (err) {
util.log("Error occured");
}
if (!team) {
util.log("The team does not exist");
} else {
res.send("Found team: " + team.name);
}
});
});
The code gets the Team successfully where util.log(team) is. It prints this to the console:
{
__v: 0,
_id: 5106e7ef9afe3a430e000007,
name: 'Team Name',
key: 1359407087999
}
This also works when sending it to the web page as well.
But when I try to send the Team's name to the web page, I get the following output with the res.send method => Found team: undefined...And when I try to output team.name instead of team to the console, I get the error Cannot call method 'toString' of undefined
Here is my Team mongoose schema as well:
var Team = new Schema({
'key' : {
unique : true,
type : Number,
default: getId
},
'name' : { type : String,
validate : [validatePresenceOf, 'Team name is required'],
index : { unique : true }
}
});
Team.statics.findByKey = function(key, cb){
return this.find({'key' : key}, cb);
};
module.exports.Schema = Team;
module.exports.Model = mongoose.model('Team', Team);
show team
app.get('/show/team/:key', function(req, res){
util.log('Serving request for url[GET] ' + req.route.path);
Team.findByKey(req.params.key, function(err, teamData){
util.log(teamData[0]);
if (!err && teamData) {
teamData = teamData[0];
res.json({
'retStatus' : 'success',
'teamData' : teamData
});
} else {
util.log('Error in fetching Team by key : ' + req.params.key);
res.json({
'retStatus' : 'failure',
'msg' : 'Error in fetching Team by key ' + req.params.key
});
}
});
});

Name is unique, so you should use findOne instead of find.
Team.statics.findByKey = function(key, cb){
return this.findOne({'key' : key}, cb);
};

Related

unable to find records in mongobd after await model.save in nodejs/express.js application

I have 2 models employee and tasklist.
var mongoose=require("mongoose");
var findOrCreate = require('mongoose-findorcreate');
var uniqueValidator = require('mongoose-unique-validator');
var employeeSchema = new mongoose.Schema({
empId : { type : Number , unique : true, required : true },
empName : { type : String , unique : true, required : true },
empTeam : { type : String , required : true },
created : {type : Date, default : Date.now}
});
employeeSchema.plugin(findOrCreate,uniqueValidator);
module.exports = mongoose.model("Employee", employeeSchema);
// Mongoose Tasklist Model config
var mongoose=require("mongoose");
var findOrCreate = require('mongoose-findorcreate');
var uniqueValidator = require('mongoose-unique-validator');
var tasklistSchema = new mongoose.Schema({
taskId : { type : Number , unique : true, required : true },
taskDesc : { type : String , unique : true, required : true },
taskDetails : {type : String},
taskAssignee : [{
type:mongoose.Schema.Types.ObjectId,
ref:"Employee"
}],
startDate: Date,
dueDate: Date,
taskStatus: String,
created : {type : Date, default : Date.now},
});
tasklistSchema.plugin(findOrCreate, uniqueValidator);
module.exports = mongoose.model("Tasklist", tasklistSchema);
I have an edit route where I am assigning multiple assignees to the task.
router.post("/tasklist/:id/edit", function(req,res){
Tasklist.findOneAndUpdate({_id:req.params.id},req.body.tasklist, async function(err, tasklist){
if(err){
req.flash("error", "Unable to update the tasklist record : "+err.message);
res.redirect("/employee");
} else {
var emp_id=req.body.taskAssignee.split(',');
try {
emp_id.forEach(assignee => {
return new Promise (function(resolve, reject){
Employee.findById(assignee, function(err, employee){
if(err){
console.log("error in finding employee :"+assignee);
reject("There was an error loading the employee data in to the database : "+err.message);
} else {
tasklist.taskAssignee.push(employee);
console.log("employee saved");
resolve("Employee records uploaded successfully");
}
});
});
});
console.log("Tasklist Saving....")
let savetasklist= await tasklist.save();
console.log("Tasklist Saved : ");
req.flash("success", "Updated Tasklist"+req.body.tasklist);
res.redirect("/tasklist");
} catch (err){
req.flash("error", "Updating Tasklist"+err);
res.redirect("/tasklist");
}
}
});
});
I am able to push the employee to tasklist.taskAssignee and also do a tasklist.save(). There are no errors. However, the update is not persisted in the mongoDB.
The console output looks like this.
some more logging info.
connection successful
Tasklist Saving....
employee saved: Assignee:5ebebe1476911d570448ee44Employee:{
_id: 5ebebe1476911d570448ee44,
empId: 32141,
empName: 'adsdasd',
empTeam: 'C Team',
created: 2020-05-15T16:06:44.342Z,
__v: 0
}
record pushed
Tasklist Saved :
{
taskAssignee: [
{
_id: 5ebebe1476911d570448ee44,
empId: 32141,
empName: 'adsdasd',
empTeam: 'C Team',
created: 2020-05-15T16:06:44.342Z,
__v: 0
}
],
_id: 5ebf1c4830f79c178c7f9905,
taskId: 17562,
taskDesc: 'WTX subscription process',
dueDate: 2020-05-25T18:30:00.000Z,
created: 2020-05-15T22:48:40.091Z,
__v: 0
}
Need help on this. Why is tasklist not getting persisted with employee ?
I look urcode, seems u are not waiting for promise to resolve
const promises = emp_id.map((assignee) => {
return new Promise(function (resolve, reject) {
Employee.findById(assignee, function (err, employee) {
if (err) {
console.log("error in finding employee :" + assignee);
reject(
"There was an error loading the employee data in to the database : " +
err.message
);
} else {
tasklist.taskAssignee.push(employee);
console.log("employee saved");
resolve("Employee records uploaded successfully");
}
});
});
});
await Promise.all(promises) // here wait..
Whole example.
router.post("/tasklist/:id/edit", function (req, res) {
Tasklist.findOneAndUpdate(
{ _id: req.params.id },
req.body.tasklist,
async function (err, tasklist) {
if (err) {
req.flash(
"error",
"Unable to update the tasklist record : " + err.message
);
res.redirect("/employee");
} else {
var emp_id = req.body.taskAssignee.split(",");
try {
const promises = emp_id.map((assignee) => {
return new Promise(function (resolve, reject) {
Employee.findById(assignee, function (err, employee) {
if (err) {
console.log("error in finding employee :" + assignee);
reject(
"There was an error loading the employee data in to the database : " +
err.message
);
} else {
tasklist.taskAssignee.push(employee);
console.log("employee saved");
resolve("Employee records uploaded successfully");
}
});
});
});
await Promise.all(promises)
console.log("Tasklist Saving....");
let savetasklist = await tasklist.save();
console.log("Tasklist Saved : ");
req.flash("success", "Updated Tasklist" + req.body.tasklist);
res.redirect("/tasklist");
} catch (err) {
req.flash("error", "Updating Tasklist" + err);
res.redirect("/tasklist");
}
}
}
);
});

Sending data before saving Node Js

I have this function with a Post that I want to insert the data in the database (MongoDB). First of all, I want to save the data in the model "Recetas" and after in the model "Users". And finally send the response. My problem is that is not saving in the model Users and is sending the data before saving.
This is my code
addReceta = function (req, res) {
User.findById(req.params.id, function(err, user){
if (!user){
res.send(404, 'User not found');
}
else{
fs.readFile(req.files.file.path, function (err, data) {
var id = crypto.randomBytes(16).toString("hex");
var newPath = pwd + id +req.files.file.originalFilename;
fs.writeFile(newPath, data, function (err) {
var date_created = new Date();
var date = date_created.toISOString().slice(0,10);
var receta = new Receta({
Titulo: datos2.titulo,
Username: datos2.username,
Ingredientes: datos2.ingredientes,
Dificultad: datos2.dificultad,
Descripción: datos2.descripcion,
Personas: datos2.personas,
Date_Created: date_created,
Tiempo: datos2.tiempo,
user_id: req.params.id,
imageUrl: URL + id + req.files.file.originalFilename
})
receta.save(function(err) {
if(!err) {
console.log('Created in Receta');
}
else {
console.log(error);
}
});
var UserReceta = ({
_id: receta._id,
Titulo : receta.Titulo,
Username : receta.Username,
Descripción : receta.Descripción,
Ingredientes : receta.Ingredientes,
Dificultad : receta.Dificultad,
Personas : receta.Personas,
Date_Created: date_created,
Tiempo : receta.Tiempo,
user_id : receta.user_id,
imageUrl: receta.imageUrl
});
user.Recetas.push(UserReceta);
user.save(function (err){
if (!err) {
console.log('Created in User Recetas');
}
else {
res.send(500, err);
}
});
res.send(receta);
});
});
};
});
};
Put your res.send(receta); inside the callback after saving in Users, right after the console.log:
console.log('Created in User Recetas');
res.send(receta);

How to update an array element in a mongoose db

I am trying to update the "like" of an array in my mongoose db
{
"_id" : ObjectId("59c7eb0c4a992f8702d847a4"),
"title" : "Favorite Rapper",
"token" : "9b3fd295a1",
"votes" : [
{
"like" : 0,
"vote" : "Kendric"
},
{
"like" : 0,
"vote" : "Jcole"
},
{
"like" : 0,
"vote" : "Kid Cudi"
},
{
"like" : 0,
"vote" : "Kanye"
},
{
"like" : 0,
"vote" : "A$AP Rocky"
}
],
"__v" : 0
}
I would like to find the mongoose db by the id and update the like of which ever element in the "votes" array. .
My question is How do i update my db document by first finding it by the id and then targeting the right element in the votes array to change the like property?
let express = require('express'),
router = express.Router(),
request = require('request'),
rtg = require('random-token-generator'),
db = require('./db');
router.post('/', (req, res) => {
let token = '';
rtg.generateKey({
len: 10, // Generate 16 characters or bytes of data
string: true, // Output keys as a hex string
strong: false, // Use the crypographically secure randomBytes function
retry: true // Retry once on error
}, function(err, key) {
let newVote = {
title: req.body.title,
votes: req.body.categories,
token: key
}; //end of newVote
db(newVote).save();
res.status(200).send(key);
});
}); //end of post
router.get('/:search', (req, res) => {
let search = req.params.search
console.log('votes url hit', search);
db.find({
'token': new RegExp(search, 'i')
}, function(err, vote) {
if (err) {
console.log('err', err);
res.send(500);
} else {
console.log('search was succesful', vote);
res.status(200).send(vote);
}
});
}); //end of get
router.put('/', (req, res) => {
console.log('THIS IS WHERE I WANT TO UPDATE THE DB', req.body);
res.send(200);
}); //end of get
module.exports = router;
You can use findOne to find you doc then save method to update your like.
db.findOne(findQuery, function(err, doc){
if(err) throw err;
doc.votes = doc.votes ? doc.votes : [];
doc.votes.forEach( (data, index, arr){
if(data.vote == "My Vote"){
arr[index]["like"] += 1 // or you new value;
}
});
doc.save();
})

Cast to number failed for value "XXX" at path "_id" for model "users" Mongoose Mongodb

I am having problems populating across 2 different models. User and Player. Each has a ObjectId stored for each other. My error occurs when I try to find the following populate from the User model.
User.find().populate('player_id')
Data of Users with Player_id
> db.getCollection('users').find({});
{ "_id" : ObjectId("58ea512576f3381d0cdf39a7"), "key" : "c7c7d3611f3d856f7a75eae5303e1cdf", "player_id" : ObjectId("59b3bff9605cbf7610c15837") }
Data of Players
> db.getCollection('players').find();
{ "_id" : ObjectId("59b3bff9605cbf7610c15837"), "user_id" : ObjectId("58ea512576f3381d0cdf39a7") }
User Model
var UserSchema = new Schema({
name: String,
player_id: {type: Schema.ObjectId, ref: "Player", default: null}
})
Player Model
var Player = new Schema({
fname : String,
sname : String,
user_id: {type: Schema.ObjectId, ref: "User", default: null},
});
Full Error Message
{ CastError: Cast to number failed for value "59b3bff9605cbf7610c15837" at path "_id"
at CastError (/var/www/norsemenfc.co.uk/node_modules/mongoose/lib/error/cast.js:27:11)
at SchemaNumber.cast (/var/www/norsemenfc.co.uk/node_modules/mongoose/lib/schema/number.js:231:9)
at SchemaNumber.SchemaType._castForQuery (/var/www/norsemenfc.co.uk/node_modules/mongoose/lib/schematype.js:1064:15)
at SchemaNumber.castForQuery (/var/www/norsemenfc.co.uk/node_modules/mongoose/lib/schema/number.js:282:14)
at /var/www/norsemenfc.co.uk/node_modules/mongoose/lib/schematype.js:991:18
at Array.map (<anonymous>)
at SchemaNumber.handleArray (/var/www/norsemenfc.co.uk/node_modules/mongoose/lib/schematype.js:990:14)
at SchemaNumber.castForQuery (/var/www/norsemenfc.co.uk/node_modules/mongoose/lib/schema/number.js:280:20)
at SchemaNumber.SchemaType.castForQueryWrapper (/var/www/norsemenfc.co.uk/node_modules/mongoose/lib/schematype.js:1016:17)
at cast (/var/www/norsemenfc.co.uk/node_modules/mongoose/lib/cast.js:250:39)
at model.Query.Query.cast (/var/www/norsemenfc.co.uk/node_modules/mongoose/lib/query.js:3109:12)
at model.Query.Query._castConditions (/var/www/norsemenfc.co.uk/node_modules/mongoose/lib/query.js:1145:10)
at model.Query.Query._find (/var/www/norsemenfc.co.uk/node_modules/mongoose/lib/query.js:1160:8)
at /var/www/norsemenfc.co.uk/node_modules/kareem/index.js:250:8
at /var/www/norsemenfc.co.uk/node_modules/kareem/index.js:23:7
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
message: 'Cast to number failed for value "59b3bff9605cbf7610c15837" at path "_id" for model "users"',
name: 'CastError',
stringValue: '"59b3bff9605cbf7610c15837"',
kind: 'number',
value: 59b3bff9605cbf7610c15837,
path: '_id',
reason: undefined,
[EDIT]
Query to call Users
var mongoose = require('mongoose')
User = mongoose.model('User'),
Player = mongoose.model('Player');
module.exports = {
getAll: function(passData){
return User.find().populate('player_id') //Point where failure happens
.then(function(data){
passData.userDetails = data;
return passData;
});
},
How the ObjectId's are saved
So I like to use mongoose.Types.ObjectId just to make sure, but even if i stored it as a string I don't believe this should happen.
updateUserId: function (req, res) {
var player_id = req.body.user,//string
user_email = req.body.savePlayer; //string
res.setHeader('Content-Type', 'application/json');
return User.find({
email: user_email
}).exec({})
.then(function(data){
var user_id = data[0]._id; //ObjectId
User.update({email: user_email}, {player_id: mongoose.Types.ObjectId((player_id))}, function (err) {
if(err)
res.send(JSON.stringify({status: 0}));
Player.update({_id: player_id}, {user_id: user_id}, function (err) {
if(err) {
res.send(JSON.stringify({status: 0}));
}else{
res.send(JSON.stringify({ status: 1 }));
}
})
})
});
}
Edit 2
Route
home: function (req, res) {
var passData = {};
api.getAll(passData)
.then(api.getPlayersWithoutAUser)
.then(function (passData) {
res.render('admin/users', {
user: req.user,
title: 'Admin Users',
selectedAdminMenu: 'users',
passData: passData
});
})
.catch(function (err) {
console.error(err);
});
},
I am using Mongoose ^4.11.11

embedded insertion of Array in mongodb

I have to try to store array data inside MongoDB using this query below. but every time I run this query its show success message without data means an empty array inside MongoDB,
my requirement is to store array data inside MongoDB as below query.
1). This is my node js script
this.childQuestionInfo = function(req, res, next){
try{
var quizArr = [];
var quizObj = {
'child.quiz.questionId' : req.params.questionId,
'child.quiz.score' : req.params.score,
'child.quiz.time' : new Date().toISOString()
};
quizArr.push(quizObj);
var userObj = {
'userid' : req.params.userId,
'quiz' : quizArr
};
var childinfoSave = new QuizChildInfo(userObj);
childinfoSave.save(function(err, data){
if(err) return next(err);
res.send("Child questionId score and date saved successfully" + data);
console.log("Child questionId score and date saved successfully");
});
}catch(err){
console.log('Error While Saving the child questionId score and Date ' +err);
return next(err);
}
};
2). This is my child schema
userId:{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
quiz:[
{
questionId:{
type: mongoose.Schema.Types.ObjectId,
ref: 'question'
},
score:{type:Number},
time:{type:String}
}
]
3). This is my output screen via postman
"Child questionId score and date saved successfully
{ __v: 0,\n _id: 57b9ac672c5791f8097d2132,\n levelsAttempted: [],\n quiz: [ { _id: 57b9ac672c5791f8097d2133 } ] }"
Try this using $push
this.childQuestionInfo = function(req, res, next){
try{
var queryObj={};
var childObj={};
var queryObj = {userid: req.params.userId};
var options = {safe: true, upsert: true};
childObj.questionId' : req.params.questionId,
childObj.score' : req.params.score,
childObj.time' : new Date().toISOString()
};
QuizChildInfo.findOneAndUpdate( queryObj, { $push: childObj }, options, function (err, data) {
if(err) return next(err);
res.send("Child questionId score and date saved successfully" + data);
console.log("Child questionId score and date saved successfully");
});
}catch(err){
console.log('Error While Saving the child questionId score and Date ' +err);
return next(err);
}
};

Categories