UpdateOne is not working Express and Mongodb - node.js

I am trying to update a content in Mongodb with the help of function UpdateOne but I keep getting "0 document(s) matched the filter, updated 0 document(s)". I am not sure what I am doing wrong here.
In the end you can see the attached picture from postman where I am sending the request
doucumnets.js
const database = require('../db/database.js');
const ObjectId = require('mongodb').ObjectId;
const documents = {
updateDoc: async function updateDoc(id, newContent) {
let db;
try {
db = await database.getDb();
const filter = { _id: ObjectId(id) };
const options = { upsert: false };
// // const query = {_id: "633abe851b36b295c11f74b5"};
// // const update = { $set: { contents: "Updated!!!"}};
const updatedDoc = {
$set: {
"contents": newContent
},
};
// console.log(filter);
// const result = await db.collection.updateOne( id, newContent, options );
const result = await db.collection.updateOne( filter, updatedDoc, options );
console.log(
`${result.matchedCount} document(s) matched the filter, updated ${result.modifiedCount} document(s)`,
);
return result;
} catch (error) {
return {
errors: {
message: error.message
}
};
} finally {
await db.client.close();
// console.log(db.close());
}
},
};
module.exports = documents;
route/index.js
const express = require('express');
const router = express.Router();
const documentsModel = require('../models/documents.js');
router.put("/update", async(req, res) => {
try {
const oldId = req.body.id;
const newContent = req.body.newContent;
const result = await documentsModel.updateDoc(oldId, newContent);
return res.status(201).json({ data: result});
} catch (errors) {
console.error(errors.message);
res.send(400).send('Problem with server');
}
});
module.exports = router;

Related

MongoError: Document must be a valid JavaScript object

I have a problem where MongoDB says that my object is not a valid JavaScript Object, Even though it is! This has been staying for days!
Basically, this is an account system that uses MongoDB's client, and the ObjectId for the ID.
I want to be able to fix the MongoError that says object (sent to updateOne, not filter) is not a valid JavaScript object.
Here is the code:
const { MongoClient, ObjectId } = require("mongodb");
const fs = require("node:fs");
const uri = "mongodb://127.0.0.1:27017";
if (!fs.existsSync("./db")) {fs.mkdirSync("./db")};
const client = new MongoClient(uri,{ useUnifiedTopology: true });
async function conn() {
await client.connect();
}
conn();
const database = client.db("login");
const accs = database.collection("accounts");
const myfil = {
_id: new ObjectId('63b6441832087ccc7e3edea2')
};
const users = accs.findOne(myfil);
const path = require("node:path");
const bcrypt = require('bcrypt');
const env = process.env;
var saltRounds = 10;
const AddSet = class AddSet {
constructor(user,pass) {
console.log(pass);
this.set = {[user]:pass};
this.set = Object.keys(this.set).reduce((acc, key) => {
acc[key.toString()] = this.set[key];
return acc;
}, {});
console.log(this.set);
return this.set;
}
}
const Account = class Account {
constructor(user,password) {
conn();
if (!users[user]) {
conn();
accs.updateOne(myfil,bcrypt.hash(password, saltRounds, function(err, hash)
{
try {
var a = ""+user;
return new AddSet(a.toString(),hash);
} catch(err) {
console.error("bcrypt",err);
}
}));
this.assetDir = path.join(path.join(env.SAVED_FOLDER,"/"+this.user),"/assets");
this.metaDir = this.assetDir + '/meta';
this.starterDir = path.join(path.join(env.SAVED_FOLDER,"/"+this.user),"/starters");
this.videoDir = path.join(path.join(env.SAVED_FOLDER,"/"+this.user),"/videos");
var fs = require('fs');
if (!fs.existsSync(this.assetDir)) fs.mkdirSync(this.assetDir, { recursive: true });
if (!fs.existsSync(this.starterDir)) fs.mkdirSync(this.assetDir, { recursive: true });
if (!fs.existsSync(this.videoDir)) fs.mkdirSync(this.assetDir, { recursive: true });
}
}
getAssetDir() {
return this.assetDir;
}
getStarterDir() {
return this.starterDir;
}
getVideoDir() {
return this.videoDir;
}
getMetaDir() {
return this.metaDir;
}
checkSession(pswd) {
conn();
bcrypt.compare(pswd, users[this.user], function(err, result) {
if (result) return true;
else return false;
});
}
}
module.exports = { Account, users };
I tried fixing it, making the keys strings, removing the $set, and it did not work.

NodeJS+Express+SQL Server backend application Error : Incorrect Syntax near '83' , Incorrect Syntax near '68' etc

In my application I get the following errors when I'm trying to reach GET, PUT, DELETE routes (tried POSTMAN and VSCode REST Server):
Error 1:
GET by ID : `Incorrect Syntax near '83'.`
Error 2:
GET ALL : `Incorrect Syntax near '83'.`
Error 3:
PUT : `Incorrect syntax near '85'.`
Error 4:
DELETE : `Incorrect syntax near '68'.`
I have googled the error but most of them are related to spacing errors in parameters in the SQL query but I have checked mine and the queries I have are all correct compared to those.
I suspect if this related to any SQL Server related encoding but not sure.
Below are some of my coding as a start to investigate:
eventController.js
'use strict';
const eventData = require('../data/events');
const getEvents = async (req, res, next) => {
try {
const events = await eventData.getEvents();
res.send(events);
}catch (error) {
res.status(400).send(error.message);
}
}
const getEvent = async (req, res, next) => {
try {
const eventId = req.params.id;
const oneEvent = await eventData.getById(eventId);
res.send(oneEvent)
} catch (error) {
res.status(400).send(error.message)
}
}
const updateEvent = async (req, res, next) => {
try {
const eventId = req.params.id;
const data = req.body;
const updated = await eventData.updateEvent(eventId, data);
res.send(updated);
} catch (error) {
res.status(400).send(error.message)
}
}
const deleteEvent = async (req, res, next) => {
try {
const eventId = req.params.id;
const deletedevent = await eventData.deleteEvent(eventId);
res.send(deletedevent);
} catch (error) {
res.status(400).send(error.message)
}
}
module.exports = {
getEvents,
getEvent,
updateEvent,
deleteEvent
}
eventslist.sql
SELECT [ord_type],
[ord_no],
[line_seq_no],
[lvl_no],
[cmt_type],
[cmt_seq_no],
[cmt],
[CMT_DOC_TYPE],
[EXTRA_1],
[extra_2],
[extra_3],
[extra_4],
[extra_5],
[extra_6],
[extra_7],
[extra_8],
[extra_9],
[extra_10],
[extra_11],
[extra_12],
[extra_13],
[extra_14],
[extra_15],
[FILLER_0001],
[ID],
[is_ext],
[RowVersion]
FROM [100].[dbo].[OELINCMT_SQL]
utils.js
'use strict';
const fs = require('fs-extra');
const {join} = require('path');
const loadSqlQueries = async (folderName) => {
const filePath = join(process.cwd(), 'data', folderName);
const files = await fs.readdir(filePath);
const sqlFiles = await files.filter(f => f.endsWith('.sql'));
const queries = {};
for (const sqlFile of sqlFiles) {
const query = await fs.readFileSync(join(filePath, sqlFile));
queries[sqlFile.replace(".sql", "")] = query
}
return queries;
}
module.exports = {
loadSqlQueries
}
UPDATE : Added data/events
index.js
'use strict';
const utils = require('../utils');
const config = require('../../config');
const sql = require('mssql');
const getEvents = async () => {
try {
let pool = await sql.connect(config.sql);
const sqlQueries = await utils.loadSqlQueries('events');
const list = await pool.request().query(sqlQueries.eventslist);
return list.recordset;
} catch (error) {
return error.message;
}
}
const getById = async (eventId) => {
try {
let pool = await sql.connect(config.sql);
const sqlQueries = await utils.loadSqlQueries('events');
const oneEvent = await pool.request()
.input('eventId', sql.Char(8), eventId)
.query(sqlQueries.eventbyId);
return oneEvent.recordset;
} catch (error) {
return error.message;
}
}
const updateEvent = async (eventId, eventData) => {
try {
let pool = await sql.connect(config.sql);
const sqlQueries = await utils.loadSqlQueries('events');
const update = await pool.request()
.input('eventId', sql.Char(8), eventId)
.input('cmt', sql.NVarChar(4000), eventData.cmt)
.query(sqlQueries.updateEvent);
return update.recordset;
} catch (error) {
return error.message
}
}
const deleteEvent = async (eventId) => {
try {
let pool = await sql.connect(config.sql);
const sqlQueries = await utils.loadSqlQueries('events');
const deleted = await pool.request()
.input('eventId', sql.Char(8), eventId)
.query(sqlQueries.deleteEvent);
return deleted.recordset;
} catch (error) {
return error.message
}
}
module.exports = {
getEvents,
getById,
updateEvent,
deleteEvent
}
eventbyId.sql
SELECT [ord_type]
,[ord_no]
,[line_seq_no]
,[lvl_no]
,[cmt_type]
,[cmt_seq_no]
,[cmt]
,[CMT_DOC_TYPE]
,[EXTRA_1]
,[extra_2]
,[extra_3]
,[extra_4]
,[extra_5]
,[extra_6]
,[extra_7]
,[extra_8]
,[extra_9]
,[extra_10]
,[extra_11]
,[extra_12]
,[extra_13]
,[extra_14]
,[extra_15]
,[FILLER_0001]
,[ID]
,[is_ext]
,[RowVersion]
FROM [100].[dbo].[OELINCMT_SQL]
WHERE [ord_no] = #eventId
Request for GET ALL via POSTMAN
Request for GET by ID via POSTMAN
Request for GET ALL via REST Server
RAW Body of GET ALL request
RAW Body of GET by ID request

UnhandledPromiseRejectionWarning: TypeError: questionList is not iterable

I'm trying to make questionList a global variable so both router.post can use it because questionList use aggregate to take 10 random objects from a database, but it keeps having this error:
(node:17008) UnhandledPromiseRejectionWarning: TypeError: questionList
is not iterable
const mongodb = require('mongodb');
const express = require('express');
const router = express.Router();
const app = express();
app.use(express.urlencoded());
app.use(express.json());
var questionList = async function (req, res, next) {
next();
const questionList = await req.database
.collection('questions')
.aggregate([{ $sample: { size: 10 } }])
.toArray();
return questionList;
};
app.use(questionList);
router.post('/attempts', async (req, res) => {
let correctAnswers = {};
for (const questions of questionList) {
correctAnswers[questions._id] = questions.correctAnswer;
}
let attemptQuiz = {
questions: questionList,
correctAnswers,
completed: false,
startAt: new Date(),
};
let newAttemptQuiz = await req.database
.collection('attempts')
.insertOne(attemptQuiz);
let renderAttemptsQuiz = await req.database
.collection('attempts')
.findOne({ _id: mongodb.ObjectID(`${newAttemptQuiz.insertedId}`) });
const quesShow = renderAttemptsQuiz.questions;
let objAll = [];
let quest = {};
for (const part of quesShow) {
quest._id = part._id;
quest.text = part.text;
quest.answers = part.answers;
objAll.push(quest);
}
let responseAttempt = {
_id: renderAttemptsQuiz._id,
questions: objAll,
completed: false,
startAt: new Date(),
};
res.status(200).json(responseAttempt);
});
router.post('/attempts/submit', async (req, res) => {
let correctAnswers = {};
for (const questions of questionList) {
correctAnswers[questions._id] = questions.correctAnswer;
}
const clientAnswers = req.body;
const count = 0;
for (const ques of questionList) {
if (correctAnswers[ques._id] == clientAnswers[ques._id]) {
count++;
}
}
res.json({ score: count });
});
module.exports = router;
Please help me fix this!! Thanks very much
You will need to cache your response in another variable.
let sample = []
var questionList = async function (req, res, next) {
sample = await req.database
.collection('questions')
.aggregate([{ $sample: { size: 10 } }])
.toArray()
next()
};
for (const ques of sample) {
if (correctAnswers[ques._id] == clientAnswers[ques._id]) {
count++;
}
}
Уou can also stash it in the request object.
var questionList = async function (req, res, next) {
req._sample = await req.database
.collection('questions')
.aggregate([{ $sample: { size: 10 } }])
.toArray()
next()
};
for (const ques of req._sample) {
if (correctAnswers[ques._id] == clientAnswers[ques._id]) {
count++;
}
}
Also, install your middleware on the router.
router.use(questionList);
// app.use(questionList);

Pass multiple queries in GET request to mongodb

// route.js
const express = require('express');
const router = express.Router();
const userHandler = require('../handler/user');
router.get('',userHandler.getUser);
module.exports = route
-
// Handler.js
const userController = require('../../core/controller/user');
// get user
getUser = async (req, res, next) => {
//console.log(req)
try {
let user = await userController.getUser(req.params.id, req.query.employeeStatus, req.query.department)
req.data = user
next()
}
catch (e) {
req.status = 400;
next(e)
}
}
module.exports = {getUser}
-
// controller.js
exports.getUser = async (userId,employeeStatus,department) => {
let userRecords = await userModel.getUser(userId,employeeStatus,department);
userRecords = userRecords.map(it => {
return {
id: it._id,
firstName: it.firstName,
lastName: it.lastName,
pic: it.pic,
gender: it.gender,
dob: it.dob,
maritalStatus: it.maritalStatus,
nationality: it.nationality,
streetAddress: it.streetAddress,
city: it.city,
state: it.state,
postalCode: it.postalCode,
country: it.country,
phone: it.phone,
email: it.email,
jobTitle: it.jobTitle,
department: it.department,
dateOfJoining: it.dateOfJoining,
employeeStatus: it.employeeStatus,
kra: it.kra,
assignedSupervisor: it.assignedSupervisor,
assignedSubordinate: it.assignedSubordinate,
workExperience: it.workExperience,
skills: it.skills,
password: it.password
}
})
return userRecords;
}
-
// query.js
exports.getUser = async(userId, employeeStatus, department) => {
var whereClause = '';
if (department) {
var whereClause ={ "department":department}
console.log(whereClause)
console.log( Object.keys(whereClause).length)
}
if(userId) return await model.find({"_id":userId}).exec();
if (employeeStatus){
console.log('debewbfewhfui')
if ( Object.keys(whereClause).length) {
console.log(whereClause)
whereClause += ','
console.log( whereClause.toSource())
console.log(whereClause.hasOwnProperty("employeeStatus"))
whereClause += {"employeeStatus":employeeStatus}
}
console.log(whereClause)
//whereClause = {"employeeStatus":employeeStatus}
console.log('e', Object.keys(whereClause).length)
// }])
// console.log(department)
// return await model.find({ $and: [ { $or: [{"employeeStatus": employeeStatus }] },{"department": department} ] }).exec();
// return await model.find({"employeeStatus":employeeStatus}).find({"department":department}).exec();
}
// if(department) {
// console.log('55')
// return await model.find({"department":department}).exec();
// };
// if (Object.keys(whereClause).length) {
// console.log(whereClause)
// whereClause = whereClause + ','
// }
var query = await model.find({$and : [whereClause] }).exec();
console.log('fssd',JSON.stringify(whereClause))
return query
}
I want if we pass any data department or employeestatus in query it will return data as required and if we dont pass any query then it will search all users. Can anyone help me please?
To conditionally compose the query filters depending on the parameters passed into the function, this should work:
query.js
exports.getUser = async (userId, employeeStatus, department) => {
let queryFilters = { userId, employeeStatus, department };
// The JSON stringify and parsing below would help remove undefined filter values
// i.e if userId is not provided, while employeeStatus and department are given
// the queryFilters object would only contain employeeStatus and department.
queryFilters = JSON.parse(JSON.stringify(queryFilters))
return model.find(queryFilters);
}

Seeding mongoDB data in node.js by referencing ObjectId

i'm using mongoose-data-seed to seed data into mongodb, however it has no mechanism to allow passing of ObjectId() as references to other seed files
I found a way to store the output of each of the seeders in a json file and retrieve the ObjectIds from the previous seeds to use in the current seeder. This way i can reference ObjectIds from previous seeders.
seeding-helper.js
const fs = require('fs');
// const path = require('path');
const seedersTmpDataFolder = 'seeders/bin';
class SeedingHelper {
static saveData(filename, data) {
return new Promise((resolve) => {
fs.writeFile(`${seedersTmpDataFolder}/${filename}.json`, JSON.stringify(data, null, '\t'), (err) => {
if (err) throw err;
resolve();
});
});
}
static readData(filename) {
return new Promise((resolve) => {
fs.readFile(`${seedersTmpDataFolder}/${filename}.json`, 'utf8', (err, data) => {
if (err) throw err;
resolve(JSON.parse(data));
});
});
}
}
module.exports = SeedingHelper;
resourceActions.seeder.js
const { Seeder } = require('mongoose-data-seed');
const mongoose = require('mongoose');
const ResourceAction = require('../models/resourceAction');
const SeedingHelper = require('../helpers/seeding-helper');
const { Types: { ObjectId } } = mongoose;
const data = [
{
_id: ObjectId(),
name: 'test1'
},
{
_id: ObjectId(),
name: 'test2'
},
];
class ResourceActionSeeder extends Seeder {
async shouldRun() { // eslint-disable-line class-methods-use-this
return ResourceAction.count().exec().then(count => count === 0);
}
async run() { // eslint-disable-line class-methods-use-this
let result;
await SeedingHelper.saveData('resourceActions', data)
.then(() => {
result = ResourceAction.create(data);
});
return result;
}
}
module.exports = ResourceActionSeeder;
resources.seeder.js
const { Seeder } = require('mongoose-data-seed');
const mongoose = require('mongoose');
const Resource = require('../models/resource');
const SeedingHelper = require('../helpers/seeding-helper');
const { Types: { ObjectId } } = mongoose;
class ResourcesSeeder extends Seeder {
async shouldRun() { // eslint-disable-line class-methods-use-this
return Resource.count().exec().then(count => count === 0);
}
async run() { // eslint-disable-line class-methods-use-this
let result;
await SeedingHelper.readData('resourceActions')
.then((resourceActionsData) => {
const machinesId = ObjectId();
const actionTest1 = ObjectId(resourceActionsData.find(x => x.name === 'test1')._id);
const actionTest2 = ObjectId(resourceActionsData.find(x => x.name === 'test2')._id);
const data = [
{
_id: machinesId,
name: 'machines',
actions: [
actionTest1,
actionTest2,
],
},
];
result = Resource.create(data);
if (result) SeedingHelper.saveData('resources', data);
});
return result;
}
}
module.exports = ResourcesSeeder;

Resources