Finding data between two dates by using a query in mongoose - javascript

How would I write a query which checks the createdAt and finds all objects between 2022-05-22 and 2022-06-22? I tried the following code/ API, but it didn’t give back the right data :
getPoDetails = async (req, res, next) => {
try {
let fromDate = req.query.fromDate;
let toDate = req.query.toDate;
var findQry = {};
if(fromDate && toDate) {
findQry.createdAt = {$gte: new Date(fromDate), $lte: new Date(toDate)};
}
allmodels.poDetailsModel.find(findQry)
.then(data => res.status(200).send(data))
.catch(err => res.status(400).send(err));
} catch (error) {
next(error);
}
}
API link : localhost:8000/getPoDetails?fromDate=2022-05-22&toDate=2022-06-22

Related

Why does my update in a put request overwrite the whole record in Sequelize?

I'm trying to make a "edit" feature for my project, and I'm stuck at this part..
I have a put request :
export const updateEvent = (event, id) => (dispatch, getState) => {
request
.put(`${baseUrl}/event/${id}`)
.send(event)
.then(response => {
dispatch(updatedEvent(response.body))
})
.catch(error => console.log(error))
}
This is the route for the said put, with Sequelize as ORM:
router.put('/event/:id', async (req, res, next) => {
const { id } = req.params
try {
const event = await Event.findByPk(id)
const updatedEvent = await event.update(req.body)
res.send(updatedEvent)
} catch (error) {
next(error)
}
})
When I test it with postman, everything works as expected. Where I ran into my problem is when I'm sending the put data from React in the frontend.
I have a form, and I save my data in the local state, and then dispatch it to actions like this:
handleSubmit = e => {
e.preventDefault()
const id = this.props.event.id
const updatedEvent = {
name: this.state.name,
description: this.state.description,
picture: this.state.picture,
startDate: this.state.startDate,
endDate: this.state.endDate,
userId: this.props.userId
}
this.props.updateEvent(updatedEvent, id)
}
Any value that is left empty in the form is overwriting my fields with nothing (an empty string). How do I properly handle this?
A solution is to filter your object, such that you remove any properties which have empty values and therefore won't be included in the database update.
In your router.put():
router.put('/event/:id', async (req, res, next) => {
const { id } = req.params
try {
const event = await Event.findByPk(id);
// filter req.body to remove empty values
const { body } = req;
const filteredBody = Object.keys(body).reduce((resultObj, key) => {
if(body[key] != ''){
resultObj[key] = body[key];
}
return resultObj;
}, {});
const updatedEvent = await event.update(filteredBody);
res.send(updatedEvent)
} catch (error) {
next(error)
}
})

MongoDB best approach to only POST data if it doesn't exist in the db?

What would be the best approach to only POST data into MongoDB if it doesn't exist in the table? hash would be the unique field for searching, this field is also indexed.
router.post('/', async (req, res) => {
try{
var id = null
const keywords = await db.dbConn('kw_data');
await keywords.insertOne({
result: req.body,
added: new Date(),
modified: new Date(),
hash: req.body.hash
}).then(resp => {
id = resp.insertedId
})
var data = {}
data = await keywords.findOne({_id: id});
res.status(201).send(data);
}
catch(e) {
res.status(400).send(e);
res.status(404).send(e);
res.status(500).send(e);
}
})
You can use
await keywords.update(
<query>,
<update>,
{
upsert: <boolean>,
}
);
and set
upsert:true
So you are inserting data and database will itself know if data is created it will get updated and if it does not exist the database will create it for you
I think I have got it by just doing a check on the hash, but not sure if this is the best approach, correct me if I'm wrong...
router.post('/sug', async (req, res) => {
try{
var id = null
const keywords = await db.dbConn('kw_sug');
check = await keywords.findOne({hash: req.body.hash});
if(check === null){
await keywords.insertOne({
results: req.body,
added: new Date(),
modified: new Date(),
hash: req.body.hash
}).then(resp => {
id = resp.insertedId
})
var data = {}
data = await keywords.findOne({_id: id});
res.status(201).send(data);
}else{
res.status(201).send('duplicated');
}
}
catch(e) {
res.status(400).send(e);
res.status(404).send(e);
res.status(500).send(e);
}
})

Removing Percent Encoding from Firebase Cloud Functions

The firebase function I'm currently using retrieves data from a certain branch in the database where the value may or may not have percent encoding. The value is a user's username and it's encoded if there's a '.' in the name. When the user gets a notification, it has their name in the body of it, and I'm trying to figure out how to removePercentEncoding if necessary. My cloud function:
exports.newPost = functions.database.ref('/{school}/posts').onWrite((change, context) => {
const school = context.params.school
const postUsername = admin.database().ref('/{school}/lastPost/lastPostUser').once('value')
var db = admin.database();
var val1, val2;
db.ref(`/Herrick Middle School/lastPost/lastPostUser`).once('value').then(snap => {
val1 = snap.val();
console.log(snap.val());
return val1
}).then(() => {
return db.ref("test2/val").once('value');
}).catch(err => {
console.log(err);
});
return loadUsers().then(users => {
let tokens = [];
for (let user of users) {
tokens.push(user.pushToken);
console.log(`pushToken: ${user.pushToken}`);
}
let payload = {
notification: {
title: school,
body: `${val1} just posted something.`,
sound: 'Apex',
badge: '1'
}
};
return admin.messaging().sendToDevice(tokens, payload);
});
});
function loadUsers() {
let dbRef = admin.database().ref('/Herrick Middle School/regisTokens');
let defer = new Promise((resolve, reject) => {
dbRef.once('value', (snap) => {
let data = snap.val();
let users = [];
for (var property in data) {
users.push(data[property]);
console.log(`data: ${property}`);
}
resolve(users);
}, (err) => {
reject(err);
});
});
return defer;
}
More specifically, I was hoping someone could shed some light on how to remove encoding from
val
Thanks in advance.
not sure i understand but either native JS decodeURI() or regex like this
var encoded = "john%doe%doe%bird";
console.log(encoded.replace(/%/g, "."));

Mongoose/Mongo Pagination

Using Express Node.JS along with Mongoose, and I'm trying to add pagination to my get request, however the order in which I'm getting messages is invalid. I get the correct messages with createdAt: -1/createdAt: 'desc', -createdAt, but in reverse order. (Changing to : 1 or 'asc' gives me the oldest messages, and thats not what I need)
const fetchMessages = async (req, res, chatId) => {
try {
const page = req.query.page || 0;
const limit = 25;
const take = req.query.take || limit;
const filter = { chatId: { $eq: chatId } };
let query = await Message.find(filter)
.skip(take * page)
.limit(200)
.sort('-createdAt');
// query = query.sort({ createdAt: 1 });
return res.status(200).json({ data: query });
} catch (e) {
console.log(e);
return res.status(500).json({ message: e });
}
};
Solved it..
const fetchMessages = async (req, res, chatId) => {
try {
// Required pagination param
const page = req.query.page || 0;
// Optional pagination params
const limit = req.query.limit || 25;
const take = req.query.take || limit;
const filter = { chatId: { $eq: chatId } };
let query = await Message.find(filter)
.sort('-createdAt')
.skip(take * page)
.limit(limit);
// Making newest messages come first
query = query.reverse();
return res.status(200).json({ data: query });
} catch (e) {
console.log(e);
return res.status(500).json({ message: e })

Mongoose update doesn't work

I'm trying to add blockDate into user db, but the code below doesn't make any changes. I checked out that data.username and blockDate are valid value. I get { ok: 0, n: 0, nModified: 0 } from res variable. how can I figure out what is wrong with this request?
router.post('/account/block', async (ctx, next) => {
let data = ctx.request.body
let fixedDate = parseInt(data.days)
let blockDate = DateTime.local().plus({days: fixedDate}).toISO()
let param = {
search: { username: data.username},
update: { $set: {blockDate: blockDate}}
}
try {
console.log(param)
let res = await User.update(param.search, param.update, {multi: true})
console.log("res", res)
} catch (e) {
console.log("err", e)
}
})
I can't tell you if it is supposed to be a date at all without seeing your mongoose model.
If it has the type Date your mongoose validator is probably going to filter it which could be the reason that no update is happening. You could use moment for converting the string to a date. For instance (including a few other "improvements" which you may like or not):
router.post('/account/block', async (ctx, next) => {
const data = ctx.request.body
const fixedDate = parseInt(data.days)
const blockDateString = DateTime.local().plus({days: fixedDate}).toISO()
const blockDate = moment(blockDateString)
const param = {
search: { username: data.username},
update: { blockDate }
}
try {
console.log(param)
const res = await User.update(param.search, param.update, {multi: true})
console.log("res", res)
} catch (e) {
console.log("err", e)
}
})

Categories