Hello folks I am trying to utilize the fullcalendar to display some holidays I have acquired from a json object.
JSON looks as follows.
var holidayObj = [
{
"holidayName" : "Boxing Day",
"holidayStart" : "May, 26 Oct 2014 13:00:00 EST",
"holidayEnd" : "May, 26 Oct 2014 13:00:00 EST"
}
{
"holidayName" : "Some other Day",
"holidayStart" : "May, 23 Oct 2014 13:00:00 EST",
"holidayEnd" : "May, 23 Oct 2014 13:00:00 EST"
}
];
My JS code to display the events on fullcalendar is as follows.
$.each(holidayObj, function(i, item) {
holidayNameText = item.holidayName;
console.log(holidayNameText); //"Boxing Day"
holidayStart = item.holidayStart; //May, 26 Oct 2014 13:00:00 EST
holidayEnd = item.holidayEnd; //May, 26 Oct 2014 13:00:00 EST
var eventObject = {
title: holidayNameText,
start: holidayStart,
end : holidayEnd,
allDay:true
};
$('#calendar').fullCalendar('renderEvent', eventObject, true);
console.log(eventObject.start);
});
For some reason the events don't seem to be populating on the calendar. Can anyone help me identify what the cause might may be?
Thank you.
You are missing a comma to separate the array elements:
var holidayObj = [{
"holidayName": "Boxing Day",
"holidayStart": "May, 26 Oct 2014 13:00:00 EST",
"holidayEnd": "May, 26 Oct 2014 13:00:00 EST"
}, {
"holidayName": "Some other Day",
"holidayStart": "May, 23 Oct 2014 13:00:00 EST",
"holidayEnd": "May, 23 Oct 2014 13:00:00 EST"
}];
By fixing it, it works fine (see the events in October).
Demo: http://jsfiddle.net/IrvinDominin/EGbHt/
Related
I'm currently working in Node with mongoose as a database. I have two models product and customer .whenever a customer buy a product, the current Date gets stored in SellingDate attribute of the product. Now the thing I want to achieve is that when we give a random Date as input, it should compare it with all Selling dates of all products up to one year, and return us COUNT OF ALL DATES THAT LIE BETWEEN ONE YEAR. For example , if we have 5 records in database i.e
{
"Sun Feb 25 2015" , "Fri Mar 25 2015" , "Sat Dec 25 2015" , "Mon Feb 25 2016"
}
and I give " Sun Feb 25, 2015" as input it should return 2 as output because we have two dates between Feb 2015 - Feb 2016 .... and it should compare dates in String format because I store the date in "Day Month Date Year" format ...
You could do an aggregation where you first convert the date strings to a date using $toDate and also keep track of the year using $year. Then you can $match all documents within the given date range, and finally $group by the year and $count:
YourModel.aggregate([
{ "$addFields": {
"year":{ "$year": {
"$toDate": "$date"
}
} }},
{
$match: {
// define your range of years here, it would be 2015 - 2016 in your case
year: {$gte: 2016, $lte: 2020}
}
},
{
$group: {
_id: {year: "$year"}
}
},
{
$count: "totalCountPerYearRange"
}
]);
As long as the date strings are in an array - using [] NOT {} (which defines an object that requires property:value pairs), then you can convert the strings into dates and do simple comparisons. The following will return an array, where you can simply get the array's length for the count.
let myDates = [
"Thu Jan 07 2016",
"Tue Mar 01 2016",
"Wed May 25 2016",
"Sat Jun 25 2016",
"Sun Aug 14 2016",
"Fri Nov 18 2016",
"Fri Jan 06 2017",
"Sun Apr 16 2017",
"Sun May 21 2017",
"Sun Jul 30 2017",
"Fri Sep 22 2017",
"Sun Nov 12 2017",
"Sun Dec 24 2017"
]
let firstDate = new Date("Wed May 25 2016");
let lastDate = new Date("Thu May 25 2017");
let matches = myDates.filter(d => {if (new Date(d) >= firstDate && new Date(d) <= lastDate) return d});
console.log(matches);
console.log(matches.length);
I am currently using the date-fns library in my Angular application and I am using the helper called isWeekend to return some time slot items from an array that only fall on a weekend.
However, I can't find a way to return the Weekend items after a certain time such as 'after 1pm'.
Please see below:
There are two dates with a time after 13:00:00 (1 PM)
There are two dates with a time before 13:00:00 (1 PM)
I need to adjust my filter to accommodate for the times which are after 13:00:00 (1 PM) and on the weekend.
const days = [
{ date: "Sun Jul 25 2020 15:30:00 GMT+0100 (British Summer Time)" },
{ date: "Sun Jul 25 2020 19:00:00 GMT+0100 (British Summer Time)" },
{ date: "Sat Jul 25 2020 05:00:00 GMT+0100 (British Summer Time)" },
{ date: "Sat Jul 25 2020 02:00:00 GMT+0100 (British Summer Time)" }
];
const filteredDays = days.filter((day) => {
console.log(dateFns.isWeekend(day.date));
// Need a solution for dateFns.isWeekend and after 13:00:00 or 1 PM
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.min.js"></script>
You can extract the 'hours' component of the date with the same library's getHours function, and then see if the number it returns is 13 or higher. Combined with your existing usage of isWeekend, your filter is quite simple.
Note: This library is going to run both of those functions based on the user's current locale, while your dates are specifying a timezone. Just something to keep in mind.
const days = [
{ date: "Sun Jul 25 2020 15:30:00 GMT+0100 (British Summer Time)" },
{ date: "Sun Jul 25 2020 19:00:00 GMT+0100 (British Summer Time)" },
{ date: "Sat Jul 25 2020 05:00:00 GMT+0100 (British Summer Time)" },
{ date: "Sat Jul 25 2020 02:00:00 GMT+0100 (British Summer Time)" }
];
const filteredDays = days.filter((day) => {
return dateFns.isWeekend(day.date) && dateFns.getHours(day.date) >= 13;
});
console.log(filteredDays);
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.min.js"></script>
Given this array object:
[{eventTitle=Event title 1, eventId=xyz1#google.com, startDate=Sun Mar 18 00:00:00 GMT+01:00 2018, endDate=Mon Mar 19 00:00:00 GMT+01:00 2018},
{eventTitle=Event title 2, eventId=xyz2#google.com, startDate=Tue Mar 19 00:00:00 GMT+01:00 2019, endDate=Wed Mar 20 00:00:00 GMT+01:00 2019},
{eventTitle=Event title 3, eventId=xyz3#google.com, startDate=Fri Mar 20 00:00:00 GMT+01:00 2020, endDate=Sat Mar 21 00:00:00 GMT+01:00 2020},
.
.
.]
How to efficiently retrieve the corresponding startDate to a certain eventTitle without looping/searching through the array? For example, I have Event title 2 and want to get Tue Mar 19 00:00:00 GMT+01:00 2019.
EDIT:
The array object is sorted by startDate.
You can apply a binary search on your array. Provided your array is sorted. -> O(log(n))
[obj1,obj2,obj3....obj100]
test the object in the middle (obj50), then decide if you have to
search in the half [obj1...obj49] or in the half [obj51...obj100]
Otherwise you can pass your objects (Events) into an other data structure like a tree. -> O(log(n))
Just looping through your whole array wouldn't be efficient, but if you don't repeat it with too many its would be fine as well. But sorting your array from the beginning would be the best solution.
Edit:
The following code shows a basic example of an binary search implementation.
const events = [{
eventTitle: "Event title 1",
eventId: "xyz1#google.com",
startDate: "Sun Mar 18 00:00:00 GMT+01:00 2018",
endDate: "Mon Mar 19 00:00:00 GMT+01:00 2018"
},
{
eventTitle: "Event title 2",
eventId: "xyz2#google.com",
startDate: "Tue Mar 19 00:00:00 GMT+01:00 2019",
endDate: "Wed Mar 20 00:00:00 GMT+01:00 2019"
},
{
eventTitle: "Event title 3",
eventId: "xyz3#google.com",
startDate: "Fri Mar 20 00:00:00 GMT+01:00 2020",
endDate: "Sat Mar 21 00:00:00 GMT+01:00 2020"
},
{
eventTitle: "Event title 4",
eventId: "xyz4#google.com",
startDate: "Fri Mar 21 00:00:00 GMT+01:00 2021",
endDate: "Sat Mar 22 00:00:00 GMT+01:00 2021"
},
{
eventTitle: "Event title 5",
eventId: "xyz5#google.com",
startDate: "Fri Mar 22 00:00:00 GMT+01:00 2022",
endDate: "Sat Mar 23 00:00:00 GMT+01:00 2022"
}
];
function binarySearch(array, value, borderLeft, borderRight) {
if (borderLeft <= borderRight) {
var index = Math.floor((borderLeft + borderRight) / 2);
var number = getNumberFromTitle(array[index].eventTitle);
if (number == value) {
return array[index].startDate;
} else if (number > value) {
return binarySearch(array, value, borderLeft, index - 1);
} else {
return binarySearch(array, value, index + 1, borderRight);
}
} else {
return null;
}
}
function getNumberFromTitle(title) {
var tmp = title.split(" ");
return tmp[tmp.length - 1];
}
console.log(binarySearch(events, 4, 0, events.length - 1));
You can create mapper util. First, it will loop once, O(n). Later all call will be O(1)
I have working code:
https://gist.github.com/deepakshrma/4b6a0a31b4582d6418ec4f76b7439781
function Mapper(array , key){
this.map = array.reduce(function(map, item){
var val = item[key];
if(!map[val]){
map[val] = [];
}
map[val].push(item);
return map;
},{});
}
Mapper.FIRST_INDEX = 0;
Mapper.prototype.find = function find(key){
return this.map[key] && this.map[key][Mapper.FIRST_INDEX]//return blank array
};
Mapper.prototype.findAll = function find(key, returnUndefined){
return this.map[key] && this.map[key] || (returnUndefined? undefined: []);//return blank array
};
var users = [{eventTitle:"Event title 1", eventId:"xyz1#google.com", startDate:"Sun Mar 18 00:00:00 GMT+01:00 2018", endDate:"Mon Mar 19 00:00:00 GMT+01:00 2018"},
{eventTitle:"Event title 2", eventId:"xyz2#google.com", startDate:"Tue Mar 19 00:00:00 GMT+01:00 2019", endDate:"Wed Mar 20 00:00:00 GMT+01:00 2019"},
{eventTitle:"Event title 3", eventId:"xyz3#google.com", startDate:"Fri Mar 20 00:00:00 GMT+01:00 2020", endDate:"Sat Mar 21 00:00:00 GMT+01:00 2020"}];
//How to use
var userMapper = new Mapper(users , 'eventTitle');
console.log(userMapper.find("Event title 2"));
var userToFind = ["Event title 3", "Event title 2"];
var reqUsers = userToFind.map(function(name){
return userMapper.find(name);
});
console.log(reqUsers);
If you only have the array, you have no option but to search through it.
But if you're going to have to search it more than once, you can make a single pass through it to produce a Map, so that subsequent searches are sublinear (faster than searching through the array with a loop). You'd do that like this:
const map = new Map(theArray.map(entry => [entry.eventTitle, entry.startDate]));
Then getting by title is:
const startDate = map.get("some title");
Live Example:
const theArray = [
{eventTitle: "Event title 1", eventId: "xyz1#google.com", startDate: "Sun Mar 18 00:00:00 GMT+01:00 2018", endDate: "Mon Mar 19 00:00:00 GMT+01:00 2018"},
{eventTitle: "Event title 2", eventId: "xyz2#google.com", startDate: "Tue Mar 19 00:00:00 GMT+01:00 2019", endDate: "Wed Mar 20 00:00:00 GMT+01:00 2019"},
{eventTitle: "Event title 3", eventId: "xyz3#google.com", startDate: "Fri Mar 20 00:00:00 GMT+01:00 2020", endDate: "Sat Mar 21 00:00:00 GMT+01:00 2020"},
];
// Building it:
const map = new Map(theArray.map(entry => [entry.eventTitle, entry.startDate]));
// Using it:
console.log(map.get("Event title 2")); // "Tue Mar 19 00:00:00 GMT+01:00 2019"
console.log(map.get("Event title 3")); // "Fri Mar 20 00:00:00 GMT+01:00 2020"
console.log(map.get("no such event title")); // undefined
.as-console-wrapper {
max-height: 100% !important;
}
(You can do the same thing with an object instead of a Map (just be sure to create it with Object.create(null) so it doesn't have a prototype), but Map is specifically designed for this.)
Note that this example assumes there's only one event for each title. If there may be more than one, you need to build the map differently so that it points you to an array of only entries for that title.
I am having a hard time figuring this out :(
I have an array of dates:
let myDatesArray = [
"Sun Oct 01 2017 05:30:00 GMT+0530 (IST)",
"Mon Oct 02 2017 05:30:00 GMT+0530 (IST)",
"Mon Oct 02 2017 06:30:00 GMT+0530 (IST)",
"Tue Oct 03 2017 05:30:00 GMT+0530 (IST)",
"Wed Oct 04 2017 05:30:00 GMT+0530 (IST)",
"Thu Oct 05 2017 05:30:00 GMT+0530 (IST)",
"Fri Oct 06 2017 05:30:00 GMT+0530 (IST)",
"Sat Oct 07 2017 05:30:00 GMT+0530 (IST)"]
However, I am only allowed to have one date entry per day! The array can have TWO dates for Monday, October 2nd but I would have to discard one (hence one per day). I tried using myDatesArray.filter(el => ????) but can't figure it out. Any ideas on how I could achieve this?
You could take a Set with a substring of the date strings.
let array = ["Sun Oct 01 2017 05:30:00 GMT+0530 (IST)", "Mon Oct 02 2017 05:30:00 GMT+0530 (IST)", "Mon Oct 02 2017 06:30:00 GMT+0530 (IST)", "Tue Oct 03 2017 05:30:00 GMT+0530 (IST)", "Wed Oct 04 2017 05:30:00 GMT+0530 (IST)", "Thu Oct 05 2017 05:30:00 GMT+0530 (IST)", "Fri Oct 06 2017 05:30:00 GMT+0530 (IST)", "Sat Oct 07 2017 05:30:00 GMT+0530 (IST)"],
seen = new Set,
result = array.filter(s => !seen.has(s.slice(0, 15)) && seen.add(s.slice(0, 15)));
console.log(result);
You can just compare the first 15 characters of each timestamp. The following keeps the last instance of duplicate days:
let dates = [
"Sun Oct 01 2017 05:30:00 GMT+0530 (IST)",
"Mon Oct 02 2017 05:30:00 GMT+0530 (IST)",
"Mon Oct 02 2017 06:30:00 GMT+0530 (IST)",
"Tue Oct 03 2017 05:30:00 GMT+0530 (IST)",
"Wed Oct 04 2017 05:30:00 GMT+0530 (IST)",
"Wed Oct 04 2017 06:30:00 GMT+0530 (IST)",
"Wed Oct 04 2017 07:30:00 GMT+0530 (IST)",
"Thu Oct 05 2017 05:30:00 GMT+0530 (IST)",
"Fri Oct 06 2017 05:30:00 GMT+0530 (IST)",
"Sat Oct 07 2017 05:30:00 GMT+0530 (IST)"]
let unique = dates.filter((d, i, arr) =>
d.substr(0,15) != (arr[i+1] || '').substr(0,15)
);
console.log(unique)
const singleDate = myDatesArray.reduce((acc,str) => {
acc[new Date(str).setHours(0,0,0,0)] = str;
return acc;
},{});
const filteredDates = Object.values(singleDate);
// ["Sun Oct 01 2017 05:30:00 GMT+0530 (IST)", "Mon Oct 02 2017 06:30:00 GMT+0530 (IST)", "Tue Oct 03 2017 05:30:00 GMT+0530 (IST)", "Wed Oct 04 2017 05:30:00 GMT+0530 (IST)", "Thu Oct 05 2017 05:30:00 GMT+0530 (IST)", "Fri Oct 06 2017 05:30:00 GMT+0530 (IST)", "Sat Oct 07 2017 05:30:00 GMT+0530 (IST)"]
Using the first chars something like this should work:
let dateMap = {};
myDatesArray.forEach(d => dateMap[d.substr(0,15)] = d);
myDatesArray = Object.values(dateMap);
Use Set to level to trim array from duplicate values
// array of dates
let myDatesArray = [
"Sun Oct 01 2017 05:30:00 GMT+0530 (IST)",
"Mon Oct 02 2017 05:30:00 GMT+0530 (IST)",
"Mon Oct 02 2017 06:30:00 GMT+0530 (IST)",
"Tue Oct 03 2017 05:30:00 GMT+0530 (IST)",
"Wed Oct 04 2017 05:30:00 GMT+0530 (IST)",
"Thu Oct 05 2017 05:30:00 GMT+0530 (IST)",
"Fri Oct 06 2017 05:30:00 GMT+0530 (IST)",
"Sat Oct 07 2017 05:30:00 GMT+0530 (IST)"
];
// make a Set from that array. Set automaticaly removes all duplicate values
const dateSet = new Set(myDatesArray);
// then make array out of Set.
let myDatesArrayLeveled = Array.from(dateSet);
// you now have array of unique date values
console.log(myDatesArrayLeveled);
We have an array of objects like this:
{key: "T62", currentWinnerName: "Test Register", dateCreated: Fri Jan 18 2019 18:17:50 GMT+0000 (Greenwich Mean Time)}
{key: "T68", currentWinnerName: "Test Register", dateCreated: Wed Jan 23 2019 14:57:40 GMT+0000 (Greenwich Mean Time)}
{key: "T58", currentWinnerName: "Test Register", dateCreated: Fri Jan 18 2019 15:57:45 GMT+0000 (Greenwich Mean Time)}
We need to sort the array based on the dateCreated value within the array.
I've tried various sort methods but unable to get the order to change.
if I understand correctly your object is array. then you can do like this way.
var obj = [
{
key: "T62",
currentWinnerName: "Test Register",
dateCreated: "Fri Jan 18 2019 18:17:50 GMT+0000 (Greenwich Mean Time)"
},
{
key: "T68",
currentWinnerName: "Test Register",
dateCreated: "Wed Jan 23 2019 14:57:40 GMT+0000 (Greenwich Mean Time)"
},
{
key: "T58",
currentWinnerName: "Test Register",
dateCreated: "Fri Jan 18 2019 15:57:45 GMT+0000 (Greenwich Mean Time)"}
];
let sortedObj = obj.sort(function(a,b){
return new Date(b.dateCreated) - new Date(a.dateCreated);
});
console.log(sortedObj);
Have you tried something like this :
const getTimestamp = (dateString)=> new Date(dateString).getTime();
const isOlder = (object1, object2)=> getTimestamp(object1.dateCreated) < getTimestamp(object2.dateCreated) ? -1 : 1;
const sortedArr = arr.sort(isOlder);
arr is your array. But you have to make dateCreated a string. This worked for me.