Date sorting is not working in muidatatable - reactjs

https://codesandbox.io/s/stupefied-volhard-jntyu?fontsize=14&hidenavigation=1&theme=dark
this is my codesand box code. on date column result is not showing correctly.

I think the problem with the sort behaviour is that you are trying to sort strings of dates where the year is the last element.
In case you could edit your data directly, try putting the year, the month and so on. Something like:
const data = [
...,
[
"Mason Ray",
"Computer Scientist",
"San Francisco",
39,
142000,
"2019-10-03"
]
Here is an example using date-fnslibrary to parse your input data.
A detail of how is done:
const data = [...].map(info =>
info.map((val, index) => {
const date = new Date(val)
return index === 5
? isValid(date)
? format(date, 'yyyy-MM-dd')
: val
: val
})
)

Related

How to map/filter data correctly with luxon (DateTimeNow) and ReactJs

I would like to explain my problem of the day.
I have a array which looks like this
[{status: "closed",createdAt: "2022-01-13T15:28:25.239Z"},{status: "closed",createdAt: "2022-01-10T15:28:25.239Z"},{status: "open",createdAt: "2021-11-25T15:28:25.239Z"}]
I filter to retrieve only the data with the status "closed"
const countData = data?.filter(
(item) => item.status === "closed"
);
const count = countData?.length;
this works well, it correctly returns the number to me.
I would like to add a new filter with Luxon.
I would like to take the date of today with luxon, and, as a result, display the objects that correspond to this date
const dateNow = DateTime.now().toISO();
console.log(dateNow)
2022-01-13T16:23:44.873+01:00
How can I fix this issue?
If you want to check if a given Luxon DateTime object represent the same day of today, you can use hasSame passing date as second parameter
Return whether this DateTime is in the same unit of time as another DateTime. Higher-order units must also be identical for this function to return true. Note that time zones are ignored in this comparison, which compares the local calendar time. Use DateTime#setZone to convert one of the dates if needed.
In your case, you can have something like the following code:
const DateTime = luxon.DateTime;
const input = [{
status: "closed",
createdAt: "2022-01-13T15:28:25.239Z"
}, {
status: "closed",
createdAt: "2022-01-10T15:28:25.239Z"
}, {
status: "open",
createdAt: "2021-11-25T15:28:25.239Z"
}, {
status: "closed",
createdAt: new Date().toISOString()
}];
const todayItems = input.filter(item => {
return DateTime.fromISO(item.createdAt).hasSame(DateTime.now(), 'day') && item.status == "closed";
});
console.log(todayItems)
<script src="https://cdn.jsdelivr.net/npm/luxon#2.3.0/build/global/luxon.js"></script>
Luxon has a function that let's you get a date at certain point of a parameter that's called startOf. So you can do something like:
const todayDate = DateTime.now().startOf("day");
So your todayDate variable will be your current date, but at 00:00:00 time.
And you can make the transformation of the elements date during your filter function to compare them to todayDate like this:
//Please consider that the example for today was at 2022-01-13
const array = [
{
name: "this is for today",
date: "2022-01-13T15:28:25.239Z"
},
{
name: "this was for yesterday",
date: "2022-01-12T15:28:25.239Z"
}];
const todayDate = DateTime.now().startOf("day");
const todayElements = array.filter((element) => {
return DateTime.fromISO(element.date).startOf("day").equals(todayDate);
});

find is returning only the first data of a date

find funtion is returning only first data row of array i want all rows in the array when logging nightbefore
{data.map((arr) => {
let filteredData6 = [];
var nightbefore = arr.find((o) => o.medicationTime === "night before food" );
nightbefore.Medicines.forEach((e) => {
filteredData6.push(e);
setmedicine6(filteredData6);
});
console.log(nightbefore);
arr is used to sort data by date and then i am finding all data with the medicationTime as given but only the first arry is being feched when i use find
full code i have given in codesandbox for refercence
https://codesandbox.io/s/weathered-bird-7ppy7?file=/src/App.js
Array.prototype.find is indeed only returning the first match of an array as mentioned in its documentation.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
In order to achieve your goal you'll have to use the filter prototype:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
the code will then be :
var nightbefore = arr.filter((o) => o.medicationTime === "night before food" );

How can I build some chart with Chart.js and ng2-charts using an array of revenus & budgets per month date as Data source?

I want to build some charts using Chart.js and ng2-charts. I have an array of data (week). I would like to know how to build an array of revenu-values and budget-values according to each date. These values will be shown on the Y-axis of the graph and the X-axis contains the labels ( [01, 02, 03, 04, 05, ..., 31] ) which are the month dates :
week = [
{
date = "2019-03-01",
revenu = 1000,
budget = 800
},
{
date = "2019-03-02",
revenu = 1000,
budget = 800
},
{
date = "2019-03-03",
revenu = 1000,
budget = 800
},
{
date = "2019-03-04",
revenu = 1000,
budget = 800
},
...
];
public monthChartLabels= [01, 02, 03, 04, 05, ..., 31];
public monthChartData = [
{
data: [ ? ] // Array of revenu-values according to each date
},
{
data: [ ? ] // Array of budget-values according to each date
}
];
<canvas
baseChart
[chartType]=" 'line' "
[datasets]="monthChartData"
[labels]="monthChartLabels"
[options]="monthLabels"
[legend]="true"
(chartHover)="onChartHover($event)">
</canvas>
Shalom Eli, you should map your original data to the chart's data arrays: week.map(e => e.revenu) for the revenu dataset, and week.map(e => e.budges) for the budget dataset.
Update
Based on your comment, you want to convert your week array to a map keyed by the day of the month of each record:
week.reduce((acc,v)=> ({
...acc,
[new Date(v.date).getDate()]: v
}), {})
And then use your labels array to fetch each value from this map:
revenuData = labels.map(r => this.weekMap[+r] && this.weekMap[+r].revenu);
budgetData = labels.map(r => this.weekMap[+r] && this.weekMap[+r].budget);
See this updated stackblitz: https://stackblitz.com/edit/ng2-charts-line-template-3dfmxn

Array map function in react for ternary operator

This is my array
var CountryList = [{ name: Canada, value: 1 },
{ name: USA, value: 2 }]
This is the operation I am using right now
var filterStr = nextProps.Country.value == "1" ? 'Canada' : 'USA';
Now I want to use the array CountryList in the above code using to check whether Canada or USA is selected. Is it done using map?
If it's USA I want to populate States of USA in another Dropdown. If it's Canada Then States of Canada. SO according to the Selection from this array I want to populate the States. I need to check the selected country . ie, I want to get the country name.
How to do that?
var states = {USA: [{name: 'A', value:1},..],Canada: []}
var country = CountryList.find(country => country.value == nextProps.Country.value).name;
if (states[county]){
this.setState({states: states[country], enabledStates: true});
}else{
this.setState({states: [], enabledStates: false});
}
Show the states based on the flag enabledState.
if you want an array of all countries that have the name USA for exemple, you can use filter like this :
CountryList.filter = country => country.value === 1 ;
or if want to check if USA for exemple exist in this array, you can use "find"
map is not the correct function to use over here.
You should use either find or filter function.
let country = CountryList.find((c) => (c.value === 1))
country = country && country.name

Mongodb Mapreduce join array

I have a big collection of songs and want to get most played songs per week, in a array. as example:
{
"_id" : {
"title" : "demons savaites hitas",
"name" : "imagine dragons"
},
"value" : {
"weeks" : [
{
"played" : 56,
"week" : 9,
"year" : 2014
}
]
}
}
It sometimes becomes:
{
"_id" : {
"title" : "",
"name" : "top 15"
},
"value" : {
"played" : 1,
"week" : 8,
"year" : 2014
}
}
The collection which i get the data from is named songs and new fields get added all the time when a songs get added. No unique artistnames or songtitles and every document in the collection looks like this:
{
"_id" : ObjectId("530536e3d4ca1a783342f1c8"),
"week" : 8,
"artistname" : "City Shakerz",
"songtitle" : "Love Somebody (Summer 2012 Mix Edit)",
"year" : 2014,
"date" : ISODate("2014-02-19T22:57:39.926Z")
}
I now want to do a mapreduce which add the new week to the array. It now overwrites it.
I also noted when trying to change to a array, not all the played get counted, with the new mapreduce.
The new mapreduce not working, with weeks:
map = function () {
if (this.week == 9 && this.year == 2014) emit({title:this.songtitle.toLowerCase(), name:this.artistname.toLowerCase()}, {played:1, week:this.week, year:this.year});
}
reduce = function(k, values) {
var result = {};
result.weeks = new Array();
var object = {played:0, week: 0, year: 0};
values.forEach(function(value) {
object.played += value.played;
object.week = value.week;
object.year = value.year;
});
result.weeks.push(object);
return result;
}
db.songs.mapReduce(map,reduce,{out: {reduce:"played2"}})
This is the old one i'm using with is a new field in the collection per week and song:
map = function () {
if (this.week == 10 && this.year == 2014) emit({title:this.songtitle.toLowerCase(), name:this.artistname.toLowerCase(), week:this.week, year:this.year}, {count:1});
}
reduce = function(k, values) {
var result = {count: 0,};
values.forEach(function(value) {
result.count += value.count;
});
return result;
}
db.songs.mapReduce(map,reduce,{out: {merge:"played"}})
I get the information fro the toplist right now from played2 like this:
db.played2.find({'_id.week': 9,'_id.year': 2014}).sort(array("value.count" => -1)).limit(50)
Above line can include any typo because i use mongoclient for php and needed to change it to javascript syntax for you.
What am I doing wrong?
I found out that I could do mapreduce as the code snippet above and then just get this week in a query and another one for previous week and do simple double for with a if to update this week with previous week place.
I made the script in python, which i run also for my mapreduce as a cronjob. As example:
if len(sys.argv) > 1 and sys.argv[1] is not None:
week = int(sys.argv[1])
else:
week = (datetime.date.today().isocalendar()[1]) - 1
year = datetime.date.today().year
previous_week = week - 1
client = MongoClient()
db = client.db
played = db.played
print "Updating it for week: " + str(week)
previous = played.find({"_id.week": previous_week, "_id.year": year}).sort("value.count", -1).limit(50)
thisweek = played.find({"_id.week": week, "_id.year": year}).sort("value.count", -1).limit(50)
thisplace = 1
for f in thisweek:
previous.rewind() # Reset second_collection_records's iterator
place = 1
if previous.count() > 0:
checker = bool(1)
for s in previous:
if s["_id"]["name"] == f["_id"]["name"] and s["_id"]["title"] == f["_id"]["title"]:
result = played.update({"_id.week": f["_id"]["week"], "_id.year": f["_id"]["year"], "_id.title": f["_id"]["title"], "_id.name": f["_id"]["name"]}, {"$set": {"place.previous_week":place, "place.this_week":thisplace}})
checker = bool(0)
print result
place = place + 1
if checker is True:
result = played.update({"_id.week": f["_id"]["week"], "_id.year": f["_id"]["year"], "_id.title": f["_id"]["title"], "_id.name": f["_id"]["name"]}, {"$set": {"place.previous_week":0, "place.this_week":thisplace}})
print result
else:
result = played.update({"_id.week": f["_id"]["week"], "_id.year": f["_id"]["year"], "_id.title": f["_id"]["title"], "_id.name": f["_id"]["name"]}, {"$set": {"place.previous_week":0, "place.this_week":thisplace}})
print result
thisplace = thisplace + 1
print "done."
This seems to work very good. Hopefully mongodb adds support to just update a field or anything in mapreduce to add information to a document without overwrite it.
I'm taking a stab at the structure of your collection based on your input fields, but I don't think mapReduce is the tool you want. Your apparent desired output can be achieved using aggregate :
db.collection.aggregate([
// Match a specific week and year if you want - remove if you want all
{ "$match": { "year": inputYear, "week": inputWeek } },
// Group to get the total number of times played
{ "$group": {
"_id": {
"title": { "$toLower": "$songtitle" },
"name": { "$toLower": "$artistname" },
"week": "$week",
"year": "$year"
},
played: { "$sum": 1 }
}},
// Sort the results by the most played in the range
{ "$sort": { "year": -1, "week": -1, "played": -1 } },
// Optionally limit to the top 15 results
{ "$limit": 15 }
])
That basically is what you appear to be trying to do. So this sums up the "number of appearances" as the number of times played. Then we take the additional steps of sorting the results, and optionally (if you can live with looking for one week at a time) limits the results to a set number. Those last two steps you won't get with mapReduce.
If you are ultimately looking for the "top ten" for each week, as a single query result, then you can look at this for a discussion (and methods to achieve) what we call the "topN" results problem.

Resources