How do I toggle boolean values in JSON object using express? - node.js

I am a beginner and have just finished my first MERN CRUD app. I've thought about a few ways to improve the app. The app is a todo list and has a complete button. The complete button will score a line through an item in the todo list. The complete button triggers a function which will make a post request (shown below) to the nodejs/express backend server. When the "isCompleted" field in the Mongo model is set to "true" (by default it's false), the item will be scored out. I tried to find a way to toggle the boolean values in the "isCompleted" field, whenever the complete button is clicked. This way you can unscore an item. But I just couldn't figure out how to implement this. Any ideas?
exports.updateEntry = async (req, res, next) => {
try {
const entry = await Entry.findByIdAndUpdate({_id:req.params.id}, {isCompleted: true});
return res.status(200).json({
success: true,
data: entry
});
} catch (err) {
return res.status(500).json({
success: false,
error: 'Server Error'
});
}

before the
const entry = await Entry.findByIdAndUpdate({_id:req.params.id}, {isCompleted: true});
you need to fetch the current value of the variable, should be something like this (been a long time since i worked with mongo):
const isCompleted = await Entry.findById({_id:req.params.id}).select('isCompleted')
then use !isCompleted to get the toggled value, like this:
const entry = await Entry.findByIdAndUpdate({_id:req.params.id}, {isCompleted: !isCompleted});

You can use body-parser middleware at top of your function (maybe you need it at a general level, so you can use it at index.js of your express project).
Then you can do this:
exports.updateEntry = async (req, res, next) => {
try {
const entry = await Entry.findByIdAndUpdate({_id:req.params.id}, {isCompleted: req.body.isCompleted});
return res.status(200).json({
success: true,
data: entry
});
} catch (err) {
return res.status(500).json({
success: false,
error: 'Server Error'
});}

Related

Supabase & ExpressJS having issues with errors

I have been playing around with ExpressJS I normally use FastAPI. I can't seem to generate an error using Supabase.
I have this endpoint
app.delete('/api/delete-book/:id', cors(corsOptions), async (req, res) => {
const {data, error} = await supabase
.from('books-express')
.delete()
.match({id: req.params.id})
if (error) {
res.status(400).send({message: `ERROR! ${error.message}`})
}
if (data)
res.send({
message: `Book ID ${req.params.id} has been deleted from the database`,
})
})
This works when it comes to deleting a book via an ID. However if I enter an invalid ID I get the data if block firing.
There is no book with an ID of 222 in the database, I would expect the error to fire but its just null
Any ideas here?
This is expected behaviour; not matching any rows is not considered an error condition in postgres.
If you'd like to check if any rows were deleted, you can use something akin to (on supabase-js 2.x):
const { data, error } = await supabase.from('books-express')
.delete()
.match({id: req.params.id})
.select() // not needed on 1.x libs
if (error || data.length === 0) {
res.status(400).send({...})
}

deleteMany only returns 1 value deleted in change streams

I have a deleteMany request but I am having a hard time in filtering my context of the deleteMany returned value. It only returns 1 value deleted from pusherjs.
Here is my change stream code and pusher code in server side;
if (schedules.operationType === 'delete') {
const scheduleDetails = schedules.documentKey;
pusher.trigger('schedules', 'deleted', {
_id: scheduleDetails._id,
teamOne: scheduleDetails.teamOne,
teamTwo: scheduleDetails.teamTwo,
user: scheduleDetails.user,
isDone: scheduleDetails.isDone,
isStarted: scheduleDetails.isStarted,
date: scheduleDetails.date,
gameEvent: scheduleDetails.gameEvent,
});
}
Here is my pusher code in client side. I am using React by the way. It is stored in my context api;
ScheduleChannel.bind('deleted', ({ deletedSchedule }) => {
console.log(deletedSchedule);
setScheduleList(
scheduleList.filter((schedule) => schedule._id !== deletedSchedule._id)
);
});
here is my code on request;
exports.deleteallmatch = async (req, res) => {
try {
const { sub } = req.user;
const deletedMatches = await Schedule.deleteMany({ user: sub });
return res.status(201).json({
message: 'All of your schedule is successfully deleted!',
deletedMatches,
});
} catch (err) {
return res.status(400).json({
message: 'Something went wrong.',
});
}
};
The delete request is fine but I want to have realtime in my app. Cuz it happened that only one data is being send instead of many. How can I solve this?
The deleteMany() method returns an object that contains three fields:
n – number of matched documents
ok – 1 if the operation was successful
deletedCount – number of deleted documents
What you can do is:
First find all elements that match your query
Store them in some variable
Perform deleting
Return the stored variable
let deleted_items = await Schedule.find({ user: sub });
await Schedule.deleteMany({ user: sub });
return res.status(201).json({
message: 'All of your schedule is successfully deleted!',
deleted_items,
});

Reading data from mongodb using sails js removes all collection data, why?

I have a sails js app,
The following codes works fine:
list: async(req, res) => {
Data.find({}).exec((err, data)=>{
if(err){
res.send(500, {message: 'db error'});
}
res.status(200).json({
message: 'Data List',
data: data
});
});
Outputs all the data of the collection correctly.
While the below code removes all the data from the mongo db collection and then shows a empty array:
list: async(req, res) => {
const data = await Data.find({});
if(!data){
res.send(500, {message: 'db error'});
}
res.status(200).json({
message: 'Data List',
data: data
});
}
I do not understand why so, I am more comfortable with async await also it makes code look cleaner hence I wanted to use the below method. Please help how can I make the below code snippet to work just like the above one.
It worked fine, when used
const data = await Data.find();
instead of
const data = await Data.find({});

What return value of sequelize when update?

I am write API in expressjs with Sequence. But I got problem with return value when update!
I follow a tutorial on internet but it got error when num=[1] not num=1 although updating success!
exports.update = (req, res) => {
const { id } = req.params;
Post.update(req.body, {
where: { id }
})
.then((num) => {
if (num === 1) {
res.send({
message: 'Post was updated successfully.'
});
}
else {
res.send({
message: `Cannot update Post with id=${id}. Maybe Post was not found or req.body is empty!`
});
}
})
.catch((err) => {
res.status(500).send({
message: `Error updating Post with id=${id}`
});
});
};
So, what return value after call update method? and how do I solve it? Thanks.
The sequelize document of update is
public static async update(values: object, options: object): Promise<Array<number, number>>
Promise<Array<number, number>>
The promise returns an array with one or two elements. The first element is always the number of affected rows, while the second element is the actual affected rows (only supported in postgres with options.returning true).
So, it will not return only the number. you need to follow the document.
To resolve
.then((nums) => {
const num = nums[0]
.....

Pass URL parameter into Database query in nodejs

I am trying to pass URL parameter into the SQL query. I have a column called "puppy_id" and one of the values is puppy1.
I want to call this URL :- localhost:3000/api/puppies/puppy1
and it should execute the query in the database SELECT * FROM puppytable WHERE puppy_id='puppy1' and return the output.
I have no problem to connect to the database. But, it is showing that no data returned. I think, I am doing something wrong in executing the query.
My Code :-
index.js
var express = require('express');
var router = express.Router();
var db = require('../queries');
router.get('/api/puppies/:puppy_id', db.getPuppyStatus);
module.exports = router;
queries.js
module.exports = {
getPuppyStatus: getPuppyStatus
};
function getPuppyStatus(req, res, next) {
var puppyID = parseInt(req.params.puppy_id);
db.any('select * from puppytable where puppy_id =$1', puppyID)
.then(function (data) {
res.status(200)
.json({
status: 'success',
data: data,
message: 'Retrieved puppies'
});
})
.catch(function (err) {
return next(err);
});
}
queries.js is in root of project directory.
It is calling from here in index.js
var db = require('../queries');
This is my output :-
{"status":"success","data":[],"message":"Retrieved puppies"}
To debug when I am doing console.log(puppyID); , it is giving me NaN
What should be the recommended way to do this ?
I don't see where req.params.family_id is coming from, but it looks like it should be req.params.puppy_id - as below - otherwise it would be undefined, which would not match anything in your database.
function getPuppyStatus(req, res, next) {
var puppyID = req.params.puppy_id;
//call puppy_id, not family_id
//puppy_id is also a string being passed in, it can't be turned into an integer
db.any('select * from puppytable where puppy_id =$1', puppyID)
.then(function (data) {
res.status(200)
.json({
status: 'success',
data: data,
message: 'Retrieved puppies'
});
})
.catch(function (err) {
return next(err);
});
}
You're converting to a number a string "puppy1". This is the reason you're getting NaN.
I don't know what's the type of the id in your column.
You've two options:
id as number, try to send a number instead of a string and you're code should be fine.
id as string, remove the parseInt.
var puppyID = req.params.puppy_id;

Resources