Postgresql: How to write insert query using where clause - node.js

Let say we have a table called user and it has userId column.
user
----
userId
we have another table called Team and it has 2 columns userId and leadId.
Team
----
userId
leadId
condition 1:
I want to insert data into Teams table and that values, should be in user table. In other words userId and leadId of Teams table should of userId of user table. Otherwise it throws an error that id does not exists in user table.
condition 2:
one more condition is userId and leadId can't be same. This is done by using if check.
here is my API code
router.post('/', checkToken, async (req, res) => {
try {
const { body } = req;
const {
userId,
leadId
} = body
const dataToInsert = {
userId,
leadId
}
if (userId == leadId) {
res.status(300).json({ error: "Lead id and user can't be same." })
}
else {
const data = await db.Team.create(dataToInsert)
res.status(200).json({
data
})
}
} catch (e) {
console.log("Error in inserting team lead", e)
res.status(500).json({
error: "Internal Server Error",
status: false,
})
}
})
export default router;
Please help how to handle the condition 1.
update:
this is what i tried now
const IdCount= await db.User.findAll({
attributes: [[db.Sequelize.fn('count', db.Sequelize.col('id')), 'getIdCount']],
where: { "id": userId && leadId }
});
output of IdCount:
here is the output, the getIdCount value is 0 which is correct but it send me whole object, how i can get only getIdCount value?
[
user {
dataValues: { getIdCount: '0' },
_previousDataValues: { getIdCount: '0' },
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [Array]
},
isNewRecord: false
}
]

You just need to make sure both users exist in the Users table (execute two queries against the Users table) and then insert a record into the Teams table.
It's better to use an explicit transaction to get both users and insert a record into Teams.
To get either you have a user in DB you can use count:
const whereClause = userId ? {
where: {
id: userId,
}
} : {}
const userCount = await db.User.count({
where: {
id: userId
}
})
const userExists = count === 1;
The same way you can check leadId

here is what i have done, it giving me correct responses on all condtions
router.post('/admin/assign', checkToken, authorize('admin'), async (req, res) => {
try {
const { body } = req;
const {
userId,
leadId
} = body
const dataToInsert = {
userId,
leadId
}
const idCount = await db.User.count({ where: { [Op.or]: [{ id: userId }, { id: leadId }] } })
if (userId == leadId) {
res.status(400).json({ error: "Lead id and user can't be same." })
}
else if (idCount == 2) {
const data = await db.Team.create(dataToInsert)
res.status(200).json({
data
})
}
else {
res.status(400).json({ error: "UserId or LeadId doesn't exist" })
}
} catch (e) {
console.log("Error in inserting team lead", e)
res.status(500).json({
error: "Internal Server Error",
status: false,
})
}
})
export default router;

Related

Node express check mongo object id exists in array if not exist then update

I have a list of array in mongo what I need to do is push Id in list of array and check that if Id exist then it will not push
Right now I push like this
const eventUserGoing = async (req, res) => {
try {
const updateuserGoinginEvent = await Events.findByIdAndUpdate(
req.body.eventid,
{
$push: {
userGoing: req.user.user_id,
},
},
{
new: true,
}
);
res
.status(200)
.json({
success: true,
message: 'Event saved successfully',
data: updateuserGoinginEvent,
});
} catch (err) {}
};
I think if its possible by aggregate but don't get what's best what to do this.
Try to use findOneAndUpdate if the event with _id does not already contain the user.
If that is the case, $push the new user:
const eventUserGoing = async (req, res) => {
try {
const updateuserGoinginEvent = await Events.findOneAndUpdate(
{ _id: req.body.eventid, userGoing: { $ne: req.user.user_id } },
{
$push: {
userGoing: req.user.user_id,
},
},
{
new: true,
}
);
res.status(200).json({
success: true,
message: 'Event saved successfully',
data: updateuserGoinginEvent,
});
} catch (err) {}
};

How to update only specific field in object within an array Mongodb

Expense Tracker application : Nodejs, Mongodb
Trying to Create a function that will update only the passed fields from request inside an array of objects
Database Schema
const updateExpense = async (req, res) => {
try {
let db = mongo.getDb()
let { macro, micro, amount, note } = req.body;
let { username, id } = req.query
let expense = await db.collection("Expense").updateOne({ username: username, "expenses.expense_id": ObjectId(id) }, { $set: {
"expenses.$.macro": macro,
"expenses.$.micro": micro,
"expenses.$.amount": amount,
"expenses.$.note": note }
});
res.status(200).json({
message: "Expense Updated",
expense: expense
});
} catch (err) {
res.status(500).json({
message: err.message
});
}
}
The above function is replacing all other fields with null
If the user is passing only the micro field, then the other fields should remain the same and only the micro field should change and other fields should not change.
Need A MongoDB Query which will only change what is required based on the data passed in req
I think you must first fetch from the database with findOne then update that fields set in req.body, something like this:
const updateExpense = async (req, res) => {
try {
let db = mongo.getDb()
let { macro, micro, amount, note } = req.body;
let { username, id } = req.query
let expense = await db.collection("Expense").findOne({ username: username });
let special_ex = expense.expenses.find(ex => ex.expense_id === ObjectId(id);
special_ex.macro = macro ? macro : special_ex.macro;
special_ex.micro = micro ? micro : special_ex.micro;
/*
and so on ...
*/
await expense.update();
res.status(200).json({
message: "Expense Updated",
expense: expense
});
} catch (err) {
res.status(500).json({
message: err.message
});
}
}

How to update all the data that have same field without modify other data in mongoose?

I have this message collection compose of 4 fields _id, conversationId, message, seen. In my message controller every time the user click specific user the backend will send a list of messages that have same conversationId into the frontend(reactJS). In the frontend that list of messages will be modify by changing the value of seen from false to true. Then I'm planning to pass this to the backend. My problem is how can I modify only all the data that have same conversationId without replacing all of the data inside message collection
Controller that will get all the messages that have same conversationID
export const getMessage = async (req, res) => {
try {
const message = await messageModel
.find({
conversationId: req.params.messageId,
})
.populate('senderId');
res.status(200).json(message);
} catch (error) {
res.status(500).json({ msg: error.message });
}
};
Return Value
[
{
_id: '616d76e858abdc3fa4059ee3',
conversationId: '61696e3ed94cd23f8c22f75a',
message: 'Sample One',
seen: false
},
{
_id: '616d779458abdc3fa4059f53',
conversationId: '61696e3ed94cd23f8c22f75a',
message: 'Sample Two',
seen: false
}
]
Frontend function that will change the value of seen
const handleUpdateSeen= (conversation) => {
dispatch(updateTaskSeenById(conversation));
};
Value that will sending to backend and the output that I want to be change on messageCollection
[
{
_id: '616d76e858abdc3fa4059ee3',
conversationId: '61696e3ed94cd23f8c22f75a',
message: 'Sample One',
seen: true
},
{
_id: '616d779458abdc3fa4059f53',
conversationId: '61696e3ed94cd23f8c22f75a',
message: 'Sample Two',
seen: true
}
]
Solution I made
export const updateMessageSeen = async (req, res) => {
try {
var updatedData;
for (let i = 0; i < req.body.length; i++) {
update = {
_id: req.body[i]._id,
conversationId: req.body[i].conversationId,
senderId: req.body[i].senderId._id,
messageText: req.body[i].messageText,
messageMedia: req.body[i].messageMedia,
seen: req.body[i].seen,
createdAt: req.body[i].createdAt,
};
}
await messageModel.updateMany(
{ conversationId: req.params.conversationId },
updatedData
);
} catch (error) {
res.status(500).json({ msg: error.message });
}
};
You may use Model.updateMany to update multiple documents in a collection.
export const seenMessageById = async (req, res) => {
try {
if (Array.isArray(req.body) && req.body.length > 0) {
const idList = req.body.map( message => message._id);
const result = await messageModel.updateMany({ _id: { $in: idList }}, { seen: true });
res.status(200).json({ msg: `Total ${result.nModified} documents updated` });
} else {
res.status(400).json({ msg: 'Atleast 1 message required to update.' });
}
} catch (error) {
res.status(500).json({ msg: error.message });
}
};

How to use dynamic filters in where on sequelize?

In my route I am trying to get the registers with a dynamic columns, than the client request the route like a "router.get('/get-by/'" than specify the field of my table...
I'm using like this
var field = req.body.field
Territory
.findOne({
where: {
field : req.params.id
}
})
but nothing works. Can anyone help me?
Try this. [field]
var field = req.body.field
Territory
.findOne({
where: {
[field] : req.params.id
}
})
I'm using like this:
var column = dynamicTable[0]
var value = dynamicTable[1]
HasReports.create({
ReportId: req.body.id,
[column]: value, // Changable for report type..
ReportedById: req.user.id,
reportHasTitle: req.body.reportHasTitle,
reportDescription: req.body.description,
reportedByIp: ip
})
im sloved with this :
router.get('/get-by/',
passport.authenticate('jwt',{ session: false}),
[
query('field').not().isEmpty().withMessage('territory field is empty'),
query('value').not().isEmpty().withMessage('territory value is empty'),
],
function(req, res) {
var token = getToken(req.headers);
if (token) {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
let filters = {}
filters[req.query.field] = req.query.value;
Territory.
findAll({
where: filters
})
.then((territory) => {
if (!territory) {
return res.status(401).send({
message: 'Territory not found.',
});
}
res.json({ success: true, territory: territory });
})
.catch((error) => res.status(400).send(error));
} else {
return res.status(403).send({success: false, msg: 'Unauthorized.'});
}
});

Preventing duplicating entries with Mongoose and Node.Js

So I have a student grades object
[
{
_id: '5bf43c42a09e1129b8f0cd4c',
user: '5bc89dec5f6e1103f808671b',
StudentGrades: [
{
_id: '5bf43daf58f0f803d4e9760b',
classCode: 'ENG1A0',
gradeLevel: 12,
credit: 1,
mark: 67
}
],
__v: 0
}
];
I use the following backend code to make entries into the database
router.put('/:user_id', function(req, res) {
let id = req.params.user_id;
const gradeFields = {
classCode: req.body.classCode,
gradeLevel: req.body.gradeLevel,
credit: req.body.credit,
mark: req.body.mark
};
if (gradeFields)
passport.authenticate('jwt', { session: false }),
UserGrades.findOneAndUpdate(
{ user: id },
{ $push: { StudentGrades: gradeFields } },
{ new: true },
{ unique: true },
function(err) {
if (err) {
res.send(err);
} else {
res.send(gradeFields);
}
}
);
});
Everything is working but at this time, a person can have duplicate classes.
In the express code i tried using {unique: true} and tried setting the classCode mongoose model to unique as well, but it didn't work. Help would be appreciated
Validate that the user_id maps to an existing user.
Validate that this user does not already have a StudentGrade with the supplied classCode.
Update the document and return the updated user.
router.put('/:user_id', async (req, res) => {
const { user_id } = req.params;
const gradeFields = {
classCode: req.body.classCode,
gradeLevel: req.body.gradeLevel,
credit: req.body.credit,
mark: req.body.mark
};
try {
// Authenticate with Passport
await passport.authenticate('jwt', { session: false });
// Grab user with this user_id
const existingUser = await UserGrades.findOne({ user: user_id });
if(!existingUser) {
// If user does not exist, throw 404
res.status(404).send("User with this ID does not exist");
}
// Check if user has classCode already on an existing StudentGrade
if(existingUser.StudentGrades.some(sg => sg.classCode === req.body.classCode)) {
res.status(409).send("Student already has grade with this class code.");
}
// Update user record with new StudentGrade and return updates document
const updatedUser = await UserGrades.findOneAndUpdate(
{ user: user_id },
{ $push: { StudentGrades: gradeFields } },
{ new: true }
);
res.status(200).send(updatedUser);
} catch (e) {
console.log('Failed to update user grades', e);
// Unknown server error, send 500
res.status(500).send(e)
}
});

Resources