I am currently creating an animal shelter web app using mern and i have trouble grouping data by date month. so i have this schema for the rescued date:
const animalSchema = new mongoose.Schema({
date_rescued: {
type: Date,
default: Date.now,
},
})
module.exports = mongoose.model('Animal', animalSchema);
And here on my animal controller backend this is my query for fetching the datas:
exports.getRescuedChart = async(req,res,next) => {
const rescuedanimals = await Animal.find({}).select(['date_rescued']);
res.status(200).json({
success:true,
rescuedanimals,
})
}
the data that this function is returning to the state is this:
what i want to have is group them by data and count how many object has the same date.
rescuedanimals =[
{
date_rescued: "April",
animal_count: 8
}
]
so yeah i just learn how to do it myself so here's what i did.
first is that i installed dataeformat library: 'npm install dateformat'
i import it on my project: import dateFormat from 'dateformat';
what i did first is to change the date format and reduce duplicate dates.
const groups = rescuedanimals.reduce(
(groups, rescued_animal) => {
const date = dateFormat(rescued_animal.date_rescued[0], "mmmm")
if (!groups[date]) {
groups[date]=[]
}
groups[date].push(rescued_animal);
return groups;
}, {}
)
after that i created a new function to put this on an arraay and also to get the legnth of the objects that are in that date.
const groupArrays = Object.keys(groups).map((date) => {
return {
date,
games: groups[date].length
};
});
thanks to Austin Greco: https://stackoverflow.com/a/46802505/12398637
Related
I am having trouble updating a boolean object and i am getting error every time-
this is the object-
const mongoose = require('mongoose');
const PlantProductSchema = new mongoose.Schema({
waterMotor: {
state: {
type: Boolean,
default: false,
time: { type: Date, default: Date.now },
}
},
});
module.exports = mongoose.model('PlantProduct', PlantProductSchema);
this is the update action-
plantProduct.waterMotor.update({state: idResultsObj.motorState });
idResultsObj.motorStat is boolean i chacked
on the other hand when I change I do this -
plantProduct.waterMotor.state = idResultsObj.motorState;
it works but It doesn't give a time stamp.
I appreciate any help I get!!
you are not using the update function correctly. it accepts two arguments, the first is the document to be updated and the second is the action.
you need to pass the id (or any other field like username) of the document that is being updated as the first argument.
plantProduct.waterMotor.update({_id: id}, {state: idResultsObj.motorState });
These are a couple of API which mongoose support for an update operation.
Regarding your code you have used update in the wrong way. update is the property of the Model object that why you are getting undefined. thought said below is the query that might help you.
const mongoose = require('mongoose');
const PlantProductSchema = new mongoose.Schema({
waterMotor: {
state: {
type: Boolean,
default: false,
time: {
type: Date,
default: Date.now
},
}
},
});
const ProductModel = mongoose.model('PlantProduct', PlantProductSchema);
const filterQuery = {}
const updateQuery = {
$set: {
"waterMotor.state": true
}
}
ProductModel.update(filterQuery, updateQuery, function(error, result) {
if (error) {
console.log(error)
} else {
console.log(response)
}
})
I am new to Node.js and I'm developing a REST API for one of my project.
In this case, I have a post request which needs to store some form data to a database. Some values come from form data and some values are generated based on that form values. For example, based on duration value, it needs to calculate final data based on that value. If the duration is 3 months, the final date should change based on the current date. If the duration value is one year, a final date should be changed based on duration with the current date.
I developed a function named releasedfinaldate() to get the date but I cannot pass that function value to the Object. How can I pass that value to Article Object? Please help..
router.post('/', (req, res, next)=>{
const articles = new Articles({
//articleId: new mongoose.Types.ObjectId(),
first_name: req.body.first_name,
last_name: req.body.last_name,
address: req.body.address,
id_number: req.body.id_number,
phone_number: req.body.phone_number,
amount: req.body.amount,
weight: req.body.weight,
duration: req.body.duration,
addtional_details: req.body.addtional_details,
interest_paid: req.body.interest_paid,
speacial_circumstances: req.body.speacial_circumstances,
released_date: req.body.released_date,
released_amount: req.body.released_amount,
date: moment().format('MMMM Do YYYY, h:mm:ss a'),
released_final_date: releasedfinaldate(req.body.duration)
});
function releasedfinaldate(duration) {
const oneyear = moment().add(365, 'days').calendar();
const threemonths = moment().add(90, 'days').calendar();
const released_final_date= null;
if (duration === 1) {
return oneyear
} else if (duration === 3) {
return threemonths
}
}
//console.log(releasedfinaldate(3))
articles.save()
.then(result =>{
console.log(result);
})
.catch(err => console.log(err));
res.status(200).json({
message:'New Article successfully created.',
createdArticle: articles
});
});`
Somehow your date function takes some time to return the date value and meanwhile, the next statement should execute. That is a reason your function returns undefined.
Never forgot NodeJS executes the statement asynchronously.
We should use a promise when we need to execute the statement synchronously.
I have tested this snippet in repl.it.
I am not saying I have done my code with the most qualified way but I have given you a solution that you should use this type of similar way for synchronous execution.
You should also async..await in place of promise.
const moment = require('moment');
function generateObject(releasedfinaldate) {
return new Promise((resolve) => {
const articles = {
first_name: "first_name",
last_name: "last_name",
address: "address",
id_number: "id_number",
phone_number: "phone_number",
amount: "amount",
weight: "weight",
duration: "duration",
addtional_details: "res",
interest_paid: "interest_paid",
speacial_circumstances: "speacial_circumstances",
released_date: "released_date",
released_amount: "released_amount",
date: moment().format('MMMM Do YYYY, h:mm:ss a'),
released_final_date: releasedfinaldate
};
resolve(articles);
});
}
function releasedfinaldate(duration) {
return new Promise((resolve) => {
const oneyear = moment().add(365, 'days').calendar();
const threemonths = moment().add(90, 'days').calendar();
const released_final_date = null;
if (duration === 1) {
return resolve(oneyear);
} else if (duration === 3) {
return resolve(threemonths)
}
});
}
releasedfinaldate(3)
.then((releasedfinaldate) => {
console.log(releasedfinaldate);
return generateObject(releasedfinaldate)
}).then((article) => {
console.log(article);
});
I'm trying to read array from Async storage with "reminders" key.
Problem is JSON.parse cannot convert 'time' key of element in Array to Date object.
I need to read from storage, parse and assign to reminders state using setReminders()
// EXAMPLE DATA IN ASYNC STORAGE
[{day: 'Monday', time: '2020-04-03T15:17:07.554Z', status: false},
{day: 'Friday', time: '2020-04-03T15:17:07.951Z', status: true},]
// LOAD REMINDERS
useEffect(readReminders, []);
function readReminders() {
AsyncStorage.getItem('reminders').then(value =>setReminders(value));
}
You can parse Date from string using Date.parse(string) or new Date(string) like:
function readReminders() {
AsyncStorage.getItem('reminders').then(values => {
const reminders = values.map(item => {
return {
...item,
time: new Date(item.time)
}
});
});
}
I have add the same issue with the date . try using moment instead of new Date()...
'npm install moment
import moment from "moment";
const time= '2020-04-03T15:17:07.554Z';
const todate= moment(time);
Hope this will help.
How fetch data between two dates with axios ?
This is what I've tried so far:
const res = axios.get("/activities", {
params: {
date: {
gte: startDate,
lte: endDate
},
user: id
}
});
Ok so I read the documentation of strapi and I have the issue :
const res = axios.get("/activities", {
params: {
date_lt: startDate,
user: id
}
});
It's not precise to add _lt or _gt at the end of the value I want to check
I am wondering if there is a way I can construct mongo's queries to take advantage of es6 default parameters. I have the following method. I want to return all the data if make, model and year is not specified. I am trying to find an elegant solution but so far all I can think of is manual if else.
getStyles({ make = '', model = '', year = '-1' }) {
return this.db
.collection('styles')
.find({ 'make.niceName': make, 'model.niceName': model, 'year.year': parseInt(year) })
.toArray();
}
Note:
This is causing some confusion. I am using destructing on purpose. The problem is not how to write this function. The problem is how to construct a mongo query so it would ignore empty values.
Assuming getStyles is your own method, sure, you can give make, model, and year defaults. You can also give a default for the whole object you're destructuring so caller doesn't have to pass anything:
function getStyles({make = '', model = '', year = '-1'} = {}) {
// Overall default ------------------------------------^^^^^
return // ...
}
The question is not how to organize/write my function but how to use es6 features to write a cleaner code that would work with mongo. I.E if the user didn't pass anything I want to return all the styles but mongo actually looks for empty fields so it doesn't return anything.
It sounds to me like you don't want default parameters (except perhaps the overall default). Instead, you want to automate how you build the object you pass find.
Given your code example, you can readily do that with Object.keys on your object. So accept as an object, e.g.:
function getStyles(options = {}) {
...an then build your find options based on options:
const findParams = {};
Object.keys(options).forEach(key => {
findParams[key + ".niceName"] = options[key];
});
Live example:
function getStyles(options = {}) {
const findParams = {};
Object.keys(options).forEach(key => {
findParams[key + ".niceName"] = options[key];
});
console.log(`find options: ${JSON.stringify(findParams)}`);
}
let results = getStyles({make: "Ford", model: "Mustang"});
results = getStyles({make: "Ford", model: "Mustang", year: 2017});
If the mapping of the name you accept (make) to the name you need for find (make.niceName) isn't as easy as just appending .niceName, it's easy enough to have a Map (or just object) you build once:
const paramNames = new Map([
["make", "make.niceName"],
["model", "model.niceName"],
["year", "year.niceName"]
]);
...and then use:
const findParams = {};
Object.keys(options).forEach(key => {
const paramName = paramNames.get(key);
if (paramName) {
findParams[paramName] = options[key];
}
});
Live example:
const paramNames = new Map([
["make", "make.niceName"],
["model", "model.niceName"],
["year", "year.niceName"]
]);
function getStyles(options = {}) {
const findParams = {};
Object.keys(options).forEach(key => {
const paramName = paramNames.get(key);
if (paramName) {
findParams[paramName] = options[key];
}
});
console.log(`find options: ${JSON.stringify(findParams)}`);
}
let results = getStyles({make: "Ford", model: "Mustang"});
results = getStyles({make: "Ford", model: "Mustang", year: 2017});
Side note: Defaults don't have to be strings, so if you use numbers for year rather than strings, your default would just be -1, not '-1'.