Cannot access mongoose schema attribute - node.js

So... I basically search an item in the database, find it, print it fine but I can t access the attributes. When I try to print them they show undefined.
I know that the attribute are in fact undefined because it doesn t break the loop and I do have both attributes in my mongoose schema. I also tried to stringify and parse it to json back and didn t work. (this is all the material I could find)
This is the script:
const name_to_find = 'Copac';
async function myFetch(){
const express = require('express');
const mongoose = require('mongoose');
const Item = require('./models/Item');
const mongoUrl = process.env.MONGO_URL;
const appsc = express();
var connectWithRetry = function() {
return mongoose.connect(mongoUrl, { useNewUrlParser: true, useUnifiedTopology: true }, function(err) {
if (err) {
console.error('Failed to connect to mongo on startup - retrying in 3 sec', err);
setTimeout(connectWithRetry, 3000);
}
});
};
connectWithRetry();
var date1 = new Date();
while(true){
var date2 = new Date();
if(date1.getTime() - date2.getTime() > 100000)
break;
try {
const response = await Item.find({name: name_to_find});
var mergi = JSON.parse(JSON.stringify(response));// doesn t work
//if (response['status'] == 1)
if(response.status == 1){
console.log("200");
break;
}
else {
console.log(JSON.stringify(response));
console.log(response.status);
console.log(mergi.name);
}
}
catch (err) {
console.error(err);
console.log(name_to_find);
}
}
}
myFetch();
this is the schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ItemSchema = new Schema({
status: {
type: Number,
required: true
},
name: {
type: String,
required: true
}
});
module.exports = Item = mongoose.model('item', ItemSchema);
and this is the output:
[{"_id":"60fc235414d05a001a5fa630","status":1,"name":"Copac","__v":0}]
undefined undefined
As u see, it is indeed 1 and should exit the loop but it doesn t.
nothing here helped either link.

Ok so the problem was that mongoose treats the result of .find() function as an array and I should have casted it with results[0] or use .findOne(). I chose the former. The answer was actually in the link provided but u have to scroll a bit for it. Tell me if u want me to delete this

Related

Why can't I get the error VersionError: No matching document found for id

I want to intentionally generate the VersionError: No matching document found for id .... error in mongoose.
Based on what I read in this question here: Mongoose - Version Error: No matching document found for id
it seems like Mongoose will try to protect against duplicate save() because it has some kind of version control.
To try to intentionally generate this error, I wrote this script:
// file: app.js
const dotenv = require('dotenv');
dotenv.config();
const mongoose = require('mongoose');
const opts = {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: true,
authSource: 'admin',
};
const schema = mongoose.Schema({
serialNumber: { type: String },
customId: { type: String },
});
const Cms = mongoose.model('Cms', schema);
const run = async () => {
try {
await mongoose.connect(process.env.MONGODB_URL, opts);
const cms1 = await Cms.findOne({});
const cms2 = await Cms.findOne({});
const randomString = new Date().toString();
cms1.serialNumber = `${randomString}AA`;
cms1.customId = `${randomString}AA`;
await cms1.save();
cms2.serialNumber = `${randomString}BB`;
await cms2.save();
} catch (e) {
console.log('err', new Date(), e.toString());
}
/* eslint-disable no-process-exit */
process.exit();
};
run();
I made sure I had exactly 1 record in my cms collection. Then I ran node app.js. I did not get any errors and I see the cms record in my mongo was updated.
I updated my run() to use a setTimeout() like this:
const run = async () => {
try {
await mongoose.connect(process.env.MONGODB_URL, opts);
const cms = await Cms.findOne();
let randomString = new Date().toString();
setTimeout(async () => {
randomString = new Date().toString();
cms.serialNumber = `${randomString}BB`;
// cms.customId = `${randomString}BB`;
await cms.save();
/* eslint-disable no-process-exit */
process.exit();
}, 2000);
cms.serialNumber = `${randomString}AA`;
cms.customId = `${randomString}AA`;
await cms.save();
} catch (e) {
console.log('err', new Date(), e.toString());
}
};
The node app.js ran successfully again and mongoose also saved the record inside the setTimeout.
How do I intentionally generate the VersionError: No matching document found for .... error? What am I missing?

model.save() not working using Mongoose and MongoDB Atlas

I am new to using MongoDB, and trying to save some data into MongoDB Atlas using Mongoose. I am possibly doing something blatantly wrong, but I do not understand why it is not working. I get no response from it, no error.
Here is the code:
File 1:
const SavedGuild = require('./models/guild.js');
module.exports = new class {
async get(id) {
return await SavedGuild.findById(id)
|| await new SavedGuild({ _id: id }).save();
}
}
(I have tried SavedGuild({ _id: id }).markModified("guild").save(), same result)
File 2 (./models/guild.js):
const { model } = require('mongoose');
class GeneralModule {
prefix = '/';
blacklistedChannelIds = [];
}
module.exports = model('guild', {
_id: String,
general: { type: Object, default: new GeneralModule() }
});
Mongoose is initiated with this code:
const mongoose = require('mongoose');
try {
mongoose.connect(
`${process.env.mongourl}`,
{ useNewUrlParser: true, useUnifiedTopology: true },
() => console.log("Mongoose is connected")
);
} catch (e) {
console.log("Mongoose could not connect");
}
All help appreciated!

Mongoose: Saving ref of another document into an array of objects document returns empty array

I'm trying to add specific document's ref id into another document's array of object. So that I can use populate method. But somehow the array remains empty even after pushing the ref.
Please help me. Thank you in advance.
Here is list.js:
const mongoose = require('mongoose');
const User = require('./user');
const Task = require('./task');
const Schema = mongoose.Schema;
// User Schema
const ListSchema = mongoose.Schema({
item:{
type: String,
required: true
},
purpose:{
type: String,
required: true
},
user: {
type: Schema.ObjectId,
ref:"User"
},
deadline:{
type: Date,
default: null
}
});
const List = module.exports = mongoose.model('List', ListSchema);
task.js:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const List = require('./list');
// User Schema
const TaskSchema = mongoose.Schema({
task:{
type: String,
required: true
},
list: [{
type: Schema.Types.ObjectId,
ref:'List'
}]
});
const Task = module.exports = mongoose.model('Task', TaskSchema);
Here is how I create and save new task instance:
const express = require('express');
const mongoose = require('mongoose');
const router = express.Router();
let List = require('../models/list');
let User = require('../models/user');
let Task = require('../models/task');
router.post('/add', isAuthenticated, function(req,res){
var tasker = req.body.task, listshash= [];
var startIndex = 0, index;
var x,y,listid= [];
while ((index = tasker.indexOf("#", startIndex)) > -1) {
var ind = tasker.indexOf(" ", index);
if(ind == -1)
listshash.push(tasker.substring(index+1));
else
listshash.push(tasker.substring(index+1,ind));
startIndex = index + 1;
}
//Instance of task
var taskIns = new Task({task: req.body.task});
List.find({user: req.session.passport.user}, function(err, lists){
for(x in lists){
for(y in listshash){
if(lists[x].item.toLowerCase().replace(/\s/g,'') == listshash[y]){
//lists[x] contains the document "list" that I want to store as
//ref in list property array of task
taskIns.list.push(lists[x]);
//console.log(taskIns.list.push(lists[x]));
}
}
}
});
taskIns.save(function(err, doc){
if(err) res.json(err);
else {
console.log("Saved");
res.redirect('/lists');
}
});
});
module.exports = router;
This is how the database collection of tasks look like after inserting data:
See the data
You should have to use async npm
List.find({user: req.session.passport.user}, function(err, lists){
async.each(lists ,function(x,callback){
async.each(listhash, function(y,callback){
if(x.item.toLowerCase().replace(/\s/g,'') == y){
taskIns.list.push(x);
}
});
});
//After that you can do save the data
taskIns.save(function(err, doc){
if(err) res.json(err);
else {
console.log("Saved");
res.redirect('/lists');
}
});
});
It's not saving the refs because you are dealing with asynchronous functions; you are pushing the lists within the find() callback and the taskIns model save event happens before the push.
You can move the taskIns save operation within the find() callback or use promises to tackle the issue.
For example, using callbacks:
List.find({ user: req.session.passport.user}, (err, lists) => {
const taskIns = new Task({task: req.body.task});
for(x in lists) {
for(y in listshash) {
if(lists[x].item.toLowerCase().replace(/\s/g,'') == listshash[y]) {
taskIns.list.push(lists[x]);
}
}
}
taskIns.save((err, doc) => {
if(err) res.json(err);
else {
console.log("Saved");
res.redirect('/lists');
}
});
});

Mongoose not returning document from mongo

I am trying to get Mongoose to query my mongo instance for a specific document (using the _id attribute). I currently have the following route:
router.get('/document/', function (req, res) {
var getDocuments = function (callback) {
var options = { server: { socketOptions: { keepAlive: 1000 } } };
var connectionString = 'mongodb://user:password#server:27017/db';
var pID = req.query.id;
pID = pID.trim();
console.log(pID);
var documentArray = [];
// Connected handler
Mongoose.connect(connectionString, function (err) {
var db = Mongoose.connection.useDb('db');
var pCollection = db.collection("collection");
//grab all items from pCollection
pCollection.find({ '_id': pID }, function (error, pDocument) {
if (error) {
console.log(error);
}
if (pDocument) {
// res.send(JSON.stringify(pDocument));
console.log(pDocument);
}
else {
console.log("nothing");
}
});
db.close();
});
};
getDocuments(function () {
});
});
The result returned is not a json document and does not seem to return a usable value. What am I doing wrong? Thanks for any help in advance!
EDIT:
I went back and changed the route to the following:
router.get('/document/', function (req, res) {
var pID = req.query.id;
pID = pID.trim();
console.log(pID);
Document.findById(pID, function (error, document) {
if (error) {
console.log(error);
}
else {
console.log(document);
}
});
});
I also created the following model:
var mongoose = require('mongoose');
var DocumentSchema = require('../schemas/documents');
var Document = mongoose.model('documents', DocumentSchema, 'Documents');
module.exports = Document;
And used the following schema:
var mongoose = require('mongoose');
var DocumentSchema = new mongoose.Schema({
documenttPK: String,
locationID: String,
docName: String,
SerialNumber: String,
documentID: String,
dateEntered: Date,
activeFlag: Boolean
});
module.exports = DocumentSchema;
My app.js makes a single call to a db file:
var mongoose = require('mongoose');
mongoose.connect('mongodb://user:password#server:27017/db');
But the result is still null. Is something wrong with the above code?

How to get and set function using inside mongoose schema

How to use if condition inside schema creation,
my schema is,
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var testSchema = new Schema({
"Name":String,
"TestValue":String
}, {
collection: 'test'
});
testSchema.eachPath(function(path) {
console.log(path);
});
testSchema.path('TestValue').set(function(value) {
console.log("value: " + value);
value="FFF";
this.TestValue = value;
return value;
});
module.exports = mongoose.model('test', testSchema);
I have to change TestValue based on the if condition,how to solve the problem...pls give me some solution to solve that problem.
You have a few options here. Here are a couple:
testSchema.path('TestValue').set(function(value) {
if (value === 'uh oh') {
return 'a different value';
} else {
return value;
}
});
Or you can use a ternary if you're so inclined:
testSchema.path('TestValue').set(function(value) {
return (value === 'uh oh') ? 'a different value' : value
});

Resources