Reading from API And compare Date to display something - javascript

So, the this is about consuming an API that has a date/time property. The content should change every 3 hours by comparing current user Date/time with that of the API and also assigning past and upcoming hours in a separate an arrays to be displayed in other section of the page. I managed to assign past and upcoming dates to their respective arrays. I need to compare the date and to assign "current data" if the user Date/Time is equal to or within 3 hours in a property to display it for the whole duration of three hours.
this.dataService.getData().subscribe((data:any[])=>{
const now = new Date('2021-02-14 09:00:00');
for (const item of data) {
const apiDate = new Date(item.dateTime);
if(now.getTime() > apiDate.getTime()){
this.future.push('future dates')
} else if(now.getTime() < apiDate.getTime()){
this.past.push('past dates')
}else if(now.getTime() == apiDate.getTime()){
//in real time, they'll only be equal for one second
this.current = 'Show NOW'
}
}
This is the structure of API/Json Data retuned
[ { "number": 10, "dateTime": "2021-02-14 00:00:00" }, { "number": 20, "dateTime": "2021-02-14 03:00:00" }, { "number": 30, "dateTime": "2021-02-14 06:00:00" }, { "number": 40, "dateTime": "2021-02-14 09:00:00" }, { "number": 50, "dateTime": "2021-02-14 12:00:00" }]
a better approach to this would even be better.
Thanks

If your want to show time within range, then you can create an object with your time boundaries:
getTimeInterval = () => {
const from = new Date();
const to = new Date(from);
to.setHours(to.getHours() + 3)
return { from, to };
}
and then just check both boundaries of date from and to:
this.dataService.getData().subscribe((data:any[])=>{
const dateRange = this.getTimeInterval();
for (const item of data) {
const apiDate = new Date(item.dateTime);
if (dateRange.from.getTime() > apiDate.getTime()
&& dateRange.to.getTime() > apiDate.getTime())
{
this.future.push('future dates');
}
else if(dateRange.from.getTime() < apiDate.getTime())
{
this.past.push('past dates')
}
else if (dateRange.from.getTime() >= apiDate.getTime()
&& dateRange.to.getTime() <= apiDate.getTime())
{
this.current = 'Show NOW'
}
}

Related

How to correctly chunk two seperate type of JSON data in an array?

I'm attempting to iterate through a JSON file, retrieving the calorie count for each item and then sorting by meal and day (in total, there are only five days of data). Here is an example of an object in the array.
"Date": "Thursday",
"Name": "Shredded Chicken",
"Icon": "Chicken",
"Type": "Dinner",
"Quantity": 85,
"Units": "Grams",
"Calories": 90
Currently, the totals for breakfastCalories, lunchCalories, dinnerCalories, and snackCalories are being added together (i.e. Monday's breakfastCalories is being added to Tuesday's breakfastCalories, and so on).
GOAL The intended result is to have an array for each day, listing the total breakfastCalories, et al. for that day. This only worked for day 1, print(calTotal[18]) returns [465,380,530,153,1528,899], which is the correct array of values for breakfastCalories, lunchCalories, dinnerCalories, snackCalories, grossCalories, netCalories.
let days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]; //currently does nothing
let calTotal = [];
function setup() {
createCanvas(windowWidth, windowHeight);
loadJSON("finalJSON.json", cbSuccess, cbFail);
}
function draw() {
//to be utilized
}
function cbFail(data) {
print("Error loading JSON File");
print(data);
}
function cbSuccess(data) {
let myData = data; //load our JSON array
let calories = 0; //set a 0 starting value for calories
let breakfastCalories = 0;
let lunchCalories = 0;
let dinnerCalories = 0;
let snackCalories = 0;
let burnedCalories = 0;
for (let i = 0; i < myData.length; i++) { //count number of total entries in the dataset
if (myData[i].Type == "Breakfast") {
breakfastCalories += myData[i].Calories;
}
else if (myData[i].Type == "Lunch") {
lunchCalories += myData[i].Calories;
}
else if (myData[i].Type == "Dinner") {
dinnerCalories += myData[i].Calories;
}
else if (myData[i].Type == "Snacks") {
snackCalories += myData[i].Calories;
}
else if (myData[i].Type == "Exercise") {
burnedCalories += myData[i].Calories;
}
let grossCalories = round(breakfastCalories + lunchCalories + dinnerCalories + snackCalories);
let netCalories = round(breakfastCalories + lunchCalories + dinnerCalories + snackCalories - burnedCalories);
calTotal.push([round(breakfastCalories), round(lunchCalories), round(dinnerCalories), round(snackCalories), grossCalories, netCalories]);
}
}
More Concise Example (complete JSON data can be found here)
Example JSON
...
{
"Date": "Monday",
"Name": "Wild Pacific Sardines",
"Icon": "Fish",
"Type": "Lunch",
"Quantity": 85,
"Units": "Grams",
"Calories": 170
},
...
{
"Date": "Monday",
"Name": "Bacon, Sunday, Organic, Uncured",
"Icon": "Bacon",
"Type": "Dinner",
"Quantity": 1,
"Units": "Slice",
"Calories": 30
},
...
{
"Date": "Tuesday",
"Name": "Dressing, Vinaigrette, Lemon Pepper",
"Icon": "Oil",
"Type": "Lunch",
"Quantity": 2,
"Units": "Tablespoons",
"Calories": 200
},
For each day (Monday through Friday), add all values of Calories in Type == Breakfast together, all values ofCalories in Type == Lunch, etc, and at the end of the day, present calorie totals in an array.
You can use this code:
const data = fetch('https://api.npoint.io/0b9f68319d190f5d41ec')
.then(result => result.json())
.then((output) => {
return output;
}).catch(err => console.error(err));
data.then(items=>{
let result ={};
items.map(item=>{
let Date = item.Date;
let Type = item.Type;
if(result.hasOwnProperty(Date) && result[Date].hasOwnProperty(Type)){
result[Date][Type] += item.Calories;
}else if(result.hasOwnProperty(Date)){
result[Date][Type] = item.Calories;
}else{
result[Date]={};
result[Date][Type] = item.Calories;
}
if(Object.keys(result[Date]).length == 5){ //each day have 5 prop (Breakfast,Lunch,.)
result[Date]['netCalories'] = result[Date]['Breakfast']+result[Date]['Lunch']+result[Date]['Dinner']+result[Date]['Snacks'] - result[Date].Exercise;
result[Date]['grossCalories'] = result[Date]['Breakfast']+result[Date]['Lunch']+result[Date]['Dinner']+result[Date]['Snacks'];
}
});
console.log(result);
});

Calculate total subsciption fee based on changing subscription fees

Im trying to calculate the total subscription fee for the penalty jar at my workplace. Every month everyone pays a certain fee on top of their penalties. It started out being 20DKK and now it's 25DKK. I have the tdata in two json objects - one with persons and one with the subscription fees
It looks like this:
subscriptionFees = [
{
"id":2,
"date":"1900-01-01T00:00:00",
"amount":20.0
},
{
"id":1,
"date":"2018-05-01T00:00:00",
"amount":25.0
}
]
persons = [
{
"id":11,
"name":"Camilla",
"active":true,
"startDate":"2017-01-01",
"endDate":"1900-01-01"
},
{
"id":6,
"name":"Cathrine",
"active":true,
"startDate":"2019-03-01",
"endDate":"1900-01-01"
},
{
"id":1,
"name":"John",
"active":true,
"startDate":"2020-03-01",
"endDate":"2021-03-01"
}
]
I'm using jquery for most of my js functions. I imagine a function running through the persons-object and calculating the total subscription fee for each of them.
Maybe something like this:
$.each(persons, function (id, obj) {
totalSubscriptionfee = calculateSubscriptionfee(obj.startDate, obj.endDate);
})
function calculateSubscriptionfee(startDate, endDate){
???
}
Can someone help me with the calculateSubscriptionfee-function? The subscription fee might get changed again in the future, so the function needs to be able to adjust for that.
Thanks,
Peter
I may have made this too complicated, but wasn't sure how else to approach it. This will
first create a ranges array with start, end and amount using reduce
map the persons array, iterating through ranges to get the amount due from that range (if any)
get the total duration, in milliseconds, convert to a rough approximation of number of months, then round down using a modulus.
In the end you get a new persons array (npersons) with the total due in it.
const subscriptionFees = [{
"id": 2,
"date": "1900-01-01T00:00:00",
"amount": 20.0
},
{
"id": 1,
"date": "2018-05-01T00:00:00",
"amount": 25.0
}
]
const persons = [{
"id": 11,
"name": "Camilla",
"active": true,
"startDate": "2017-01-01",
"endDate": "1900-01-01"
},
{
"id": 6,
"name": "Cathrine",
"active": true,
"startDate": "2019-03-01",
"endDate": "1900-01-01"
},
{
"id": 1,
"name": "John",
"active": true,
"startDate": "2020-03-01",
"endDate": "2021-03-01"
}
]
let ranges = subscriptionFees.reduce((acc, a) => {
if (acc.length === 0 || Object.hasOwnProperty(acc[acc.length - 1].end)) {
let tmp = {
start: a.date,
amount: a.amount
};
acc.push(tmp)
} else {
acc[acc.length - 1].end = a.date;
acc.push({
start: a.date,
amount: a.amount
})
}
return acc;
}, [])
ranges[ranges.length - 1].end = new Date();
//console.log('ranges', ranges);
const npersons = persons.map(person => {
let ttl = 0;
// fix endDate
if (new Date(person.endDate).getTime() < new Date(person.startDate).getTime()) person.endDate = new Date();
// iterate ranges
ranges.forEach(a => {
let end = Math.min(new Date(a.end).getTime(), new Date(person.endDate).getTime())
let start = Math.max(new Date(a.start).getTime(), new Date(person.startDate).getTime())
// console.log('calculating', person.name, 'start', new Date(start), 'end', new Date(end));
let interval = end - start;
if (interval > 0){
let tmpttl = Math.floor( (interval / 1000 / 60 / 60 / 24 / 30) * +a.amount)
tmpttl -= tmpttl % a.amount
ttl += tmpttl;
}
})
person.total = ttl
return person
})
console.log(persons)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

How can I obtain a new json with only unique values from the original

I'm having a hard time trying to obtain a json that has only unique (date, hour) values from two keys combined. The json is something like this:
{
"date": "2019-07-11",
"hour": "12:00",
"idAppointmentsHour": 47914218,
"shift": "T"
},
So if they have the same date and the same shift, I want to group this info. Im using ES5, and my code so far is like this:
for (var i = 0; i < agendaDatas.length; i++) {
if (!datas.includes(agendaDatas[i].data)) {
if (!datas.includes(agendaDatas[i].turno)) {
datas.push({"date": agendaDatas[i].data});
datas.push({"shift": agendaDatas[i].shift})
}
}
}
I have tried includes
All the values from the json are being copyied. i can't use ES6 Set because the platform runs in ES5.
Basically, you could take an array of keys for a grouping identifier and use an object for grouping same groups.
function getKey(keys) {
return function (object) {
return keys.map(function (k) { return object[k]; }).join('|');
};
}
var getKeyDateShift = getKey(['date', 'shift']),
groups = Object.create(null),
result = data.reduce(function (r, o) {
var key = getKeyDateShift(o);
if (!groups[key]) {
result.push(groups[key] = { date: o.date, shift: o.shift, data: [] });
}
groups[key].data.push(o);
return r;
}, []);
You can do it with a cycle, on each iteration via .filter() check whether a match already exists. If not, then create it. Anyway, add the unique-ish values to the group:
//Test data
var items = [
{
"date": "2019-07-11",
"hour": "12:00",
"idAppointmentsHour": 47914218,
"shift": "T"
}, {
"date": "2019-07-11",
"hour": "12:01",
"idAppointmentsHour": 47914219,
"shift": "T"
}, {
"date": "2019-07-11",
"hour": "12:02",
"idAppointmentsHour": 47914220,
"shift": "T"
}, {
"date": "2019-07-11",
"hour": "12:03",
"idAppointmentsHour": 47914218,
"shift": "TY"
},
];
//The logic
var output = [];
for (var item of items) {
var existent = output.filter(function(current) {
return ((item.date === current.date) && (item.shift === current.shift));
});
existent = (existent.length ? existent[0] : {date: item.date, shift: item.shift, group : []});
if (!existent.group.length) output.push(existent);
existent.group.push({
idAppointmentsHour: item.idAppointmentsHour,
hour: item.hour
});
}

how i get the object form an array with a parameter function like this

I will only get an object in comparison the id that from is decided from the user with objects of the arrays.
var laptops = [{
"name": "Firefox",
"age": 30,
"id": "ab"
},
{
"name": "Google",
"age": 35,
"id": "cd",
"date": "00.02.1990"
},
{
"name": "Microsoft",
"id": "ef",
"age": 40
}
];
getLaptopByAsin(id: string) {
var laptop = this.laptops.find(
(laptopObject) => {
return laptopObject.name === id;
}
);
return laptop;
}
var enter = "cd";
name = this.getLaptopByAsin(enter).name;
age = this.getLaptopByAsin(enter).age;
date = this.getLaptopByAsin(enter).date;
console.log(name)
console.log(age)
console.log(date)
Your problem is that you filter on name:
this.laptops.find(
(laptopObject) => {
return laptopObject.name === id;
}
);
After fixing your issue and do some refactoring, the code becomes this:
getLaptopByAsin(id: string) {
return this.laptops.find(
laptopObject => laptopObject.id === id
);
}
Some other comments:
Try to use const instead of var more often where possible.
Saving date the way you do, might give you some headache in the future. use some standard instead, like https://en.wikipedia.org/wiki/Epoch
Avoid multiple function calls when they are not needed, save the result from getLaptopByAsin to a variable (const foundLaptop) so you don't need to iterate over the array multiple times. eg:
const foundLaptop = this.getLaptopByAsin('cd');
console.log(foundLaptop.name);
console.log(foundLaptop.age, foundLaptop.date);

Read JSON with Current Date and get key value using Javascript?

I am trying to get the count from JSON response which has current date in the key.
Json Response:
[
{
"type": {
"id": "mobile",
"name": "mobile",
"description": "",
"total_count": 0
},
"counts": [
{
"date": "2018-09-06",
"timestamp": 1536192000000,
"count": 20
},
{
"date": "2018-09-07",
"timestamp": 1536278400000,
"count": 10
}
]
},
{
"type": {
"id": "lap",
"name": "lap",
"description": "",
"total_count": 0
},
"counts": [
{
"date": "2018-09-06",
"timestamp": 1536192000000,
"count": 19
},
{
"date": "2018-09-07",
"timestamp": 1536278400000,
"count": 20
}
]
}
]
My New try as per vikscool code:
var json_count = JSON.parse(getcounts);
var curDate = getCurrentDate();
var mobilcount = () => json_count.map(ct => {
const count = ct.counts;
const getDate = count.find(dt => dt.date === curDate);
window.alert('count is ', getDate.count);
return {getDate};
});
mobilcount();
function getCurrentDate () {
var nowDate = new Date();
var month = (nowDate.getMonth() + 1).toString().length == 1
? '0' + (nowDate.getMonth() + 1)
: (nowDate.getMonth() + 1);
var day = nowDate.getDate().toString().length == 1
? '0' + nowDate.getDate()
: +nowDate.getDate();
return nowDate.getFullYear() + '-' + month + '-' + day;
}
output: "count is "
but there is no count printed from json.
Is there any solution in Javascript I can get the current date and get the counts.
I need to get the count as 10 in mobilcount.
As the dates are stored in the JSON Array key named as the counts of the first object of the json_count you can not fetch it using:
var instance_count=json_count[0].values[2].count;
As your json object does not have any key named as values.
What you have to do is first access the counts key then get the particular object from it which contains the particular(current date as in your case) and then get the counts from it.
Below is a sample code to get the particular date's count:
//assuming this is the Json response you are getting as complete JSON response is not provided by the OP.
var getcounts = `[{"type":{"id":"mobile","name":"mobile","description":"","total_count":0},"counts":[{"date":"2018-09-05","timestamp":1533686400000,"count":0},{"date":"2018-09-06","timestamp":1533772800000,"count":8}]}]`;
//parsing the given json String
var json_count = JSON.parse(getcounts);
function getCountForCurrentDate() {
var curDate = getCurrentDate(); //for which the data is to be fetched and making in format of the dates in JSON as yyyy-mm-dd
//finding the particular object that contains the current date
var searchedObj = json_count[0]['counts'].find(f => f['date'] == curDate);
if(searchedObj!==undefined)
console.log('count is', searchedObj['count']);
}
function getCurrentDate() {
var nowDate = new Date();
var month = (nowDate.getMonth() + 1).toString().length == 1 ? '0' + (nowDate.getMonth() + 1) : (nowDate.getMonth() + 1);
var day = nowDate.getDate().toString().length == 1 ? '0' + nowDate.getDate() : +nowDate.getDate();
return nowDate.getFullYear() + '-' + month + '-' + day;
}
getCountForCurrentDate();
Here in the snippet above, i have created two functions getCurrentDate() to get the current date in the format it is stored in JSON response and getCountForCurrentDate() to get the count from the json_count variable.
Update 1 as per the new requirement is given by OP
The given JSON object is as follows:
var json_count = [
{
type: {
id: "mobile",
name: "mobile",
description: "",
total_count: 0
},
counts: [
{
date: "2018-09-06",
timestamp: 1536192000000,
count: 20
},
{
date: "2018-09-07",
timestamp: 1536278400000,
count: 10
}
]
},
{
type: {
id: "lap",
name: "lap",
description: "",
total_count: 0
},
counts: [
{
date: "2018-09-06",
timestamp: 1536192000000,
count: 19
},
{
date: "2018-09-07",
timestamp: 1536278400000,
count: 20
}
]
}
];
And now as the object has two entities one for mobile and another for lap we can fetch the particular values as:
var mobile = json_count.find(f=>f['type']['id']=='mobile');//comparing the value present in the json object at location type.id to 'mobile' (change it to 'lap' or anything that is present in the id of the object).
and now to get the count for it we do as:
var mobile_count = mobile.counts.find(f=>f['date']=='2018-09-07');//replace the static date with the date you want to fetch the count from
and then access the count as:
console.log(mobile_count.count);
//output:10

Categories

Resources