I have this MapStateToProps:
const mapStateToProps = (state) => {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const ESFReport = getESFReport(state);
const resultStatusReport = getResultStatusReport(state);
return {
companInfo: getCompanyInfo(state),
companyId: getCompanyId(state),
...ESFReport,
...resultStatusReport,
year,
month,
};
};
And both ...ESFReport, and ...resultStatusReport, have the same property: report but I need somehow to change the name because in the same component I use const { report } = this.props two times but for different props.
How can I do this? (it used to work when I have only ...ESFReport, but when I added ...resultStatusReport, it broke).
Thanks in advance.
If you don't need anything other than report from the ESFReport and resultStatusReport objects you could do:
const mapStateToProps = (state) => {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const { report: ESFReport } = getESFReport(state);
const { report: resultStatusReport } = getResultStatusReport(state);
return {
companInfo: getCompanyInfo(state),
companyId: getCompanyId(state),
ESFReport,
resultStatusReport,
year,
month,
};
};
It just renames the report property on each to ESFReport and resultStatusReport. You would then have this.props.ESFReport which would actually be ESFReport.report and this.props.resultStatusReport which would be resultStatusReport.report.
Related
I'm trying to build an application that fetches a quote based on today's date. I'm using ISR in NextJS with the following code -
The page where I am using ISR -
export async function getStaticProps() {
const { currentTime, currentDate } = dateParsed;
const ref = bhagwadGitaRefs[currentDate];
// Here ref is - { chapter: 2, verse: 48,} hardcoded.
const { bhagwadGitaData } = await useBhagwadGitaQuote(ref);
return {
props: {
bhagwadGitaData,
},
revalidate: 10,
};
}
DateParsed.js
const dateObj = new Date();
export const dateParsed = {
currentDate: dateObj.getDate(),
currentMonth: dateObj.getMonth(),
currentYear: dateObj.getFullYear(),
currentTime: new Date(dateObj.getTime()).getHours(),
};
useBhagwadGitaQuote(ref);
export const useBhagwadGitaQuote = async (ref) => {
let { chapter, verse } = ref;
const options = {
method: 'GET',
headers: {
'X-RapidAPI-Key': 'someapikey',
'X-RapidAPI-Host': 'rapidapi.com',
},
};
const link = `https://bhagavad-gita3.p.rapidapi.com/v2/chapters/${chapter}/verses/${verse}/`;
const raw = await fetch(link, options);
const bhagwadGitaData = await raw.json();
return { bhagwadGitaData, isLoading: !bhagwadGitaData };
};
It is designed such that the currentDate will go into the URL of the API. But when I tried running the app the next day after building it locally, it won't revalidate the data, even though the date has changed (hence the request URL will also change, so technically it should rebuild). I refreshed it multiple times but it won't rebuild that particular page again, with new date data.
I have an app that allows users to schedule tasks. Users can set a schedule (schedule, an rrule string) as well as a timezone (scheduleTimeZone, a string e.g. Asia/Dubai).
I am trying to write a function (getNextRunAt) that gets the next occurrence of the task at a UTC date and store this in my Postgres DB as a timestamptz field.
I'm struggling to account for DST, lots of the results are an hour or even a day off.
Here's the function (in TypeScript):
import RRule from 'rrule';
import moment from 'moment-timezone';
const getNextRunAt = ({
schedule,
scheduleTimeZone,
}: {
schedule?: string | null;
scheduleTimeZone?: string | null;
}): Date | undefined => {
if (!schedule) {
return undefined;
}
const options = RRule.parseString(schedule);
if (scheduleTimeZone) {
options.tzid = scheduleTimeZone;
}
const dtstart = moment.utc().toDate();
const rule = new RRule({ ...options, dtstart, count: 1 });
const dates = rule.all();
let date = dates[0];
if (scheduleTimeZone && moment(date).tz(scheduleTimeZone).isDST()) {
date = moment(date).subtract(1, 'hour').toDate();
}
return date;
};
export default getNextRunAt;
It works for some dates/times/timezones:
Date.now = jest.fn(() => new Date('2021-03-02 10:24:27.000000Z').getTime());
const nextDate = getNextRunAt({
schedule: 'RRULE:INTERVAL=1;BYDAY=MO,TU,WE,TH,SA,FR,SU;BYMINUTE=0;BYHOUR=9;BYSECOND=0;FREQ=DAILY',
scheduleTimeZone: 'America/Los_Angeles',
});
expect(nextDate).toEqual(new Date('2021-03-02 17:00:00.000000Z'));
// WORKS
But not for others:
Date.now = jest.fn(() => new Date('2021-03-02 10:24:27.000000Z').getTime());
const nextDate = getNextRunAt({
schedule: 'RRULE:INTERVAL=1;BYDAY=MO,TU,WE,TH,SA,FR,SU;BYMINUTE=0;BYHOUR=9;BYSECOND=0;FREQ=DAILY',
scheduleTimeZone: 'America/Los_Angeles',
});
expect(nextDate).toEqual(new Date('2021-03-02 17:00:00.000000Z'));
// DOES NOT WORK
Expected: 2021-03-02T17:00:00.000Z
Received: 2021-03-03T17:00:00.000Z
I think that the last case is wrong with a day. But for others solution might look like:
const getNextRunAt = ({ schedule, scheduleTimeZone }: { schedule?: string | null; scheduleTimeZone?: string | null }): Date | undefined => {
if (!schedule) {
return undefined;
}
const options = RRule.parseString(schedule);
const dtstart = moment();
const rule = new RRule({
...options,
dtstart: dtstart.toDate(),
count: 1,
});
const dates = rule.all();
const date = dates[0];
let mDate = moment.tz(date, scheduleTimeZone);
const offset = Math.abs(mDate.utcOffset()) > 16 ? mDate.utcOffset() / 60 : mDate.utcOffset();
if (!mDate.isDST()) {
mDate = mDate.add(1, 'hours');
}
mDate.add(-offset, 'hour');
return mDate.toDate();};
I want to select the data before or after a certain date in sqlite using Typeorm where date is in milliseconds.
Here is my Query Builder:
const qb = getConnection()
.getRepository(Post)
.createQueryBuilder('p')
.where('createdAt < :cursor', {
cursor: "1624809058000"
})
.getMany()
We have to pass the date in this format: "yyyy-mm-dd HH:MM:ss.l" Example: "2000-01-01 00:00:00.000"
So, we have to convert the date in this format.
First solution
const chars = { T: ' ', Z: '' }
const dateInMilliseconds = "1624809058000"
const qb = getConnection()
.getRepository(Post)
.createQueryBuilder('p')
.where('createdAt < :cursor', {
cursor: new Date(parseInt(dateInMilliseconds))
.toISOString()
.replace(/[TZ]/g, ch => chars[ch])
})
.getMany()
Second solution
import { LessThan, MoreThan } from 'typeorm'
import { format } from 'date-fns'
// TypeORM Query Operators
const MoreThanDate = (date: Date) => MoreThan(format(date, 'yyyy-mm-dd HH:MM:SS'))
const LessThanDate = (date: Date) => LessThan(format(date, 'yyyy-mm-dd HH:MM:SS'))
const dateInMilliseconds = "1624809058000"
const posts = await Post.find({
createdAt: MoreThanDate(new Date(dateInMilliseconds))
})
Third solution
import { Between } from 'typeorm';
import { addYears, subYears } from 'date-fns';
// TypeORM Query Operators
const MoreThanDate = (date: Date) => Between(date, addYears(date, 100));
const LessThanDate = (date: Date) => Between(subYears(date, 100), date);
const dateInMilliseconds = "1624809058000"
const posts = await Post.find({
where: {
createdAt: MoreThanDate(new Date(dateInMillisecons)),
},
});
export const fetchDailyData = async () => {
try {
const { data } = await axios.get(`${url}/daily`);
let today = new Date('2020-01-27');
let referanceDay = new Date(dailyData.reportDate)
const modifiedData = data.map((dailyData) => ({
if(referanceDay => today){
confirmed: dailyData.confirmed.total,
deaths: dailyData.deaths.total,
date: dailyData.reportDate
};
}))
// return modifiedData
} catch (error) {
}
}
I am trying to compare days and return proper ones. But it's not worked. I think I got a mistake object and if section. Could you please look my problem. Thanks..
Daily data is argument to anon. Function but being referenced out in which case it would be undefined.
It looks like your >= comparison in your if statement is backwards. Also you are referencing dailyData before it is declared inside mapTry this:
export const fetchDailyData = async () => {
try {
const { data } = await axios.get(`${url}/daily`);
let today = new Date('2020-01-27');
const modifiedData = data.map((dailyData) => ({
let referanceDay = new Date(dailyData.reportDate)
if(referanceDay >= today){
confirmed: dailyData.confirmed.total,
deaths: dailyData.deaths.total,
date: dailyData.reportDate
};
}))
// return modifiedData
} catch (error) {
}
}
I think you should use a library to compare the dates. I use Moment.js for all my datetime operations.
enter link description here
example from docs :
moment('2010-10-20').isAfter('2010-01-01', 'year'); // false
I am saving state in my React app via localStorage
const [items, setItem] = useState(() => {
let itemsString = window.localStorage.getItem('items');
if (itemsString) {
try {
return JSON.parse(itemsString);
} catch (e) {
console.error(e);
return [];
}
} else {
return [];
}
})
when I JSON.parse(itemsString) the date in the state has been converted to UTC (because strings/localstorage)
How do I JSON.parse() my state and reinitialize the date string to an object?
e.g. instead of returning 2019-07-19T00:28:03.058Z return Thu Jul 18 2019 20:28:03 GMT-0400 (Eastern Daylight Time) instead
Solution I came up with the help of Aaron's suggestion below.
Store old state. Map over state array, creating new empty object and storing each property in it, store date, convert date to string and pass that into new Date object to instantiate the value back to a date object on page refresh.
const [items, setItem] = useState(() => {
let itemsString = window.localStorage.getItem('items');
if (itemsString) {
try {
const oldState = JSON.parse(itemsString);
const newState = oldState.map(item => {
const date = item.date;
const container = {}
container.id = item.id
container.item = item.item
container.date = new Date(date.toString())
container.cost = item.cost
container.type = item.type
return container;
})
return newState;
} catch (e) {
console.error(e);
return [];
}
} else {
return [];
}
})
After you parse itemString just set the date key to a new Date object
const object = JSON.parse(itemString);
const newState = {...object, date: new Date(object.date)}