Issue with date range on nodeJS - node.js

I have issues while filtering data from mongodb using nodejs and nextjs.
I am not getting some of the data stored in the database especially if the moment is not this month.
My Routes:
module.exports.getFulfullmentByDateRange = (params) => {
return Fulfillment.find({ createdOn: { $gte: moment(params.dateFrom).format('YYYY-MM-DD'), $lte: moment(params.dateTo).format('YYYY-MM-DD') } }).then(fulfillment => {
return fulfillment
})
}
This only allows me to filter selected data. What I'm trying to achieve is to get all data using the selected range from the from and to datetime picker.

Related

Update element of any particular index in an array in MongoDb using mongoose in Node.js

Hi I tried to update the element at a particular index in an array but I'm not able to update it. It is updating the entire array. Not able to figure out how to update any particular index. Also tried
{$set:{"Data.1:req.body}}
this is updating at 1st index but I don't want to hardcode the index value. It should take from frontend. Let say I have a schema in which I have Data who's type is array and default value is as shown below or anything in the same format.
Data: {
type: Array,
Default: ["0","1","0"]
}
Whenever I'll create a user then Data field will contain these default values, But now I want to update the value at any index (coming from frontend) of Data array of any user created.
I tried findByIdAndUpdate method but I don't know what to pass in set property. If I'm passing this {$set: req.body} and In postman I'm giving any value of Data then obviously it is updating Data array but I want to update value at any index which I'm passing from frontend, let say the index I'm passing is 2 then it should update the value of array at index 2, similarly I can pass any index from frontend how should I do that. What changes I have to make in {$set : } Thanks in advance.
Waiting for any help or suggestions. Thanks
It appears that you can solve this in backend logic if you are passing the index from the frontend.
You can dynamically specify the index, based on the input from the frontend, before you send a query.
const updateUserData = async (req, res) => {
const { index, user_id, new_value } = req.body;
try {
const update = {};
update[`Data.${index}`] = new_value;
const data = await Users.updateOne(
{ _id: user_id },
{ $set: update }
);
return res.status(200).json({ success: true });
} catch (error) {
return res.status(500).json({ success: false });
}
};

Unable to query between dates in DynamoDB from NodeJS Lambda

I'm having some issues trying to query between dates for a dynamboDB table using NodeJS
I'm trying to query for the data in the data between the dates in the actualReadDate column and get these columns back: meterName, meterNumber, actualReadDate,actualReadTime
I've tried a few different things I've found online, latest attempt is below
async function scanForResults(){
try {
var params = {
TableName: 'MeterReadSubmission-dev',
keyConditionExpression : 'actualReadDate between :from and :to',
ProjectionExpression : 'meterName, meterNumber, actualReadDate,actualReadTime',
ExpressionAttributeValues: {
":from": startDate,
":to": endDate
}
};
var result = await docoClient.query(params).promise()
console.log("Retrieved data: ");
console.log(JSON.stringify(result))
} catch (error) {
console.error(error);
}
}
scanForResults()
The startDate and endDate variables are declared further above with the same format as the dates stored in DynamoDB
I looked at this link: Query DynamoDB between certain dates -NodeJs
But still just can't get it to work. Thanks in advance

How do I copy entries from one collection to another using mongoose?

I'm trying to create a little task management site for a work project. The overall goal is here is that the tasks stay the same each month (their status can be updated and whatnot), and they need to be duplicated at the start of each new month so they can be displayed and sorted by on a table.
I already figured out how to schedule the task, I have the table I need set up. A little explanation before the code - the way I'm planning on doing this is having two different task collections - one I've called "assignments", will have the tasks that need to be duplicated (with their description, status and other necessary data) and another collection, which I called "tasks", will have the exact same data but with an additional "date" field. This is where the table will get it's data from, the date is just for sorting purposes.
This is what I have so far -
Index.js: gets all the assignments from the database, and sends the object over to the duplicate function.
router.get('/test', async function(req, res, next) {
let allTasks = await dbModule.getAllAssignments();
let result = await dbModule.duplicateTasks(allTasks);
res.json(result);
});
dbmodule.js:
getAllAssignments: () => {
allAssignments = Assignment.find({});
return allAssignments;
},
duplicateTasks: (allTasksToAdd) => {
try {
for (let i = 0; i < allTasksToAdd.length; i++) {
let newTask = new Task({
customername: allTasksToAdd.customername,
provname: allTasksToAdd.provname,
description: allTasksToAdd.description,
status: allTasksToAdd.status,
date: "07-2020"
})
newTask.save();
}
return "Done"
} catch (error) {
return "Error"
}
}
The issue arises when I try and actually duplicate the tasks. For testing purposes I've entered the date manually this time, but that's all that ends up being inserted - just the date, the rest of the data is skipped. I've heard of db.collection.copyTo(), but I'm not sure if it'll allow me to insert the field I need or if it's supported in mongoose. I know there's absolutely an easier way to do this but I can't quite figure it out. I'd love some input and suggestions if anyone has any.
Thanks.
The problem is that allTasksToAdd.customername (and the other fields your trying to access) will be undefined. You need to access the fields under the current index:
let newTask = new Task({
customername: allTasksToAdd[i].customername,
provname: allTasksToAdd[i].provname,
description: allTasksToAdd[i].description,
status: allTasksToAdd[i].status,
date: "07-2020"
})
Note that you can simplify this by using a for .. of loop instead:
for (const task of allTasksToAdd) {
const newTask = new Task({
customername: task.customername,
provname: task.provname,
description: task.description,
status: task.status,
date: "07-2020"
});
newTask.save();
}

Unable to perform operations over Mongoose result

Product
.findAll()
.then((products) => {
/* Perform operations */
}
The above query returns an array of products. For eg,
[
{
name: Mobile,
price: 10000
},
{
name: Laptop,
price: 20000
},
]
I need to make some changes to the products array (add new fields based on the values of existing fields, and delete those existing fields). I tried few methods, but none are working:
products.forEach((product) => {
product.[updatedPrice] = updatedPrice;
delete product[price];
}
Array.map() is also not working.
The following works, but I don't know the working behind, and why it is happening. Also, how to delete a field using the same.
products.forEach((product) => {
product.set('updatedPrice', updatedPrice, {strict: false})
}
The thing here to note is that in .then((products) products object here is not a JSON object but a Mongoose Document object and the set method you are using is defined by the mongoose. You can refer it from here https://mongoosejs.com/docs/guide.html#strict
We can do 2 things:
use lean() (returns a plain js object)
Product.findAll().lean().then((products) => {
/* Perform operations*/
});
use toJSON() method on products object to convert mongoose object to js object
Product.findAll().then((products) => {
products = products.toJSON();
/* Perform operations*/
});
Thanks

Timezone problems with MongoDB and NodeJs

So the problem I'm currently having is :
I've a list of gym classes, which every class has an OpeningTime. I want to fetch all the classes from the current day, but. I'm not getting the same result locally and in production, cause for some reason, when Im deploying my backend to Heroku, the timezone is being setted by default to UTC (when I've a GMT-3 timezone).
Here is my query :
var now = moment();
var startOfDay = now.startOf('day').format();
var endOfDay = now.endOf('day').format();
var clasesDB = await Clase.find({ $and: [{ openingTime: { $gte: startOfDay } }, { openingTime: { $lte: endOfDay } }] })
So, like I said before, the problem is ocurring when, for example:
When I fetch the classes at my local time (Ex: 02-26-19 21:00hs ( GMT-3) ), the queries are actually showing the classes from 02-27, because, at MINE 21:00hs, on the server side is already 00:00, so, the date is not 02-26 anymore. And I dont want this kind of output.
How can I get a workaround to solve this?
Thanks in advance! :)
Don't use .format(), this makes a string. Compare directly Date values, i.e. use
var now = moment();
var startOfDay = now.startOf('day').toDate();
var endOfDay = now.endOf('day').toDate();
By default moment uses local times, so moment().startOf('day') returns midnight of local time. If you want to get midnight of UTC then use moment.utc().startOf('day').
If you don't rely on "local" time zone, then you can specify it like moment.tz("America/New_York").startOf('day')
No matter which time you need, never compare Date values by string, use always actual Date value.
By default in MongoDB a date field is stored in UTC, You can create a date with offset while writing to store it in your timeZone. But you've not done it while writing documents then you need to convert date field to your required timeZone while reading data from database. Check this below example.
JavaScript Code :
const today = new Date().toLocaleDateString(undefined, {
day: '2-digit',
month: '2-digit',
year: 'numeric'
}) // 02/26/2020. If your Heroic server is in different location then specify your locale in place of undefined - whereas undefined picks local time by default. Ex:- 'en-Us' for USA
Query :
db.collection.aggregate([
{ $addFields: { timewithOffsetNY: { $dateToString: { format: "%m/%d/%Y", date: "$openingTime", timezone: "America/New_York" } } } },
{ $match: { timewithOffsetNY: today } }, { $project: { timewithOffsetNY: 0 } }
])
Above query is written for New York timeZone, you can convert it according to your timeZone, In test url you can see 1st doc is not returned though it is on 2020-02-26 cause offset to New York as of today is 5hrs, So after converting date becomes as 2020-02-25.
Test : MongoDB-Playground
Ref : $dateToString

Resources