Creating a reusable date formatter in React - reactjs

I've been struggling to create a reusable function that I can call on dates in my data. The goal is to take any date given, determine if it has just a date, or date and time, then return the data in the appropriate format.
I've been using moment to format things, but am not sure how to actually call this function on the data. I'm very new to React
Here is what I've got so far:
import moment from "moment";
const FormatDate = (dateObject) => {
var dateMutant = dateObject;
var dateMutated = "";
function justDate() {
//formats just a date
dateMutated = moment.utc(dateMutant).format("MM-DD-YYYY");
}
function dateTime() {
//formats a date and time
dateMutated = moment.utc(dateMutant).format("MM-DD-YYYY hh:mm:a");
}
console.log(dateMutated);
return dateMutated;
};
export default FormatDate
I am attempting to call it in a page like this:
React.useEffect(() => {
var testDate = '';
if (allCommentsFetch) {
setAllCommentsLoading(true);
axios
.get(`###API Hook##`)
.then(response => {
let comments = response.data;
comments.forEach(commentfield => {
if (commentfield != null) {
commentfield['commentTimestamp'] = moment.utc(commentfield.commentTimestamp).format('YYYY-MM-DD hh:mm:ss');
testDate = FormatDate(commentfield.commentTimestamp).justDate();
} else {
comments[commentfield] = 'N/A'
}
})
but am getting an error that Object(...)(...).justDate is not a function.

you can write it in a better and cleaner way, first of all, you have not to write your module names in PascalCase, getFormattedName will be a better choice! the second thing is that you are using var... avoid that.
the only thing you have to change in the format function is a format template... and as i see you have only two option (justDate and dateTime) in this case, so let's write it again:
const getFormattedDate = ({ dateObject, includeTime }) => {
const dateFormat = includeTime ? 'MM-DD-YYYY hh:mm:a' : 'MM-DD-YYYY';
return moment.utc(dateObject).format(dateFormat);
};
and about the error you got: (but am getting an error that Object(...)(...).justDate is not a function) the problem is that you didn't return justDate from the FormatDate function.

Related

React - convert date with date-fns

I have a date in this format: 12-21-2021
This date comes from a Redux selector.
So console.log('ccc', lastUpdateDate); at the beginning shows only:
ccc
and after few times shows
ccc 12-21-202
If I use new Date(lastUpdateDate).toDateString() it turns out it works only in Chrome, whereas FireFox and Safari say this is an invalid date.
So I want to convert it in the right way using a function.
So I created this function:
const parseDateWithDashes = (dateToParse) => {
console.log('dateToParse', dateToParse);
useEffect((): any => {
let finalDate;
dateToParse instanceof Date && dateToParse.getTime()
? (finalDate = format(dateToParse, "yyyy-MM-dd'T'HH:mm:ss.SSSxxx"))
: null;
console.log('finalDate', finalDate);
return finalDate;
}, [dateToParse]); //since at the beginning it is empty, it should re-run as a date is available
};
parseDateWithDashes(lastUpdateDate)
However doing this it logs out:
dateToParse (several time empty)
dateToParse 12-21-2021
finalDate undefined (several times)
I've also tried to run the function in a useEffect...
useEffect(() => {
parseDateWithDashes(lastUpdateDate);
});
But that's an invalid hook call.
What am I doing wrong? How to fix that?
I resolved it this way.
I added the parsing to the thunk. And stringified in order to avoid non-serialized errors:
const parsedDate = parse(lastUpdateDate, 'MM-dd-yyyy', new Date());
dispatch(setLastUpdateDate(JSON.stringify(parsedDate)));
Then I just formatted it in the component:
export const convertStringDateToDate = (date: string) => {
let finalDate;
try {
finalDate = JSON.parse(date);
finalDate = format(parseISO(finalDate), 'E LLL d yyyy');
} catch (e) {
finalDate = 'loading date';
}
return finalDate;
};
That works

Rendering Date from model in react

I am trying to get the date to render in a nice format. currently rendering like this
I tried
function getEndDateFromstring(){
return itinerary.endDate.split('T').slice(-1)[0]
}
then
{itinerary.name} from {getStartDateFromstring()} to {getEndDateFromstring()}
But it is throwing an error
Uncaught TypeError: Cannot read properties of undefined (reading 'split')
This looks like a scope issue, pass the itinerary to your function like below
function getEndDateFromstring(itinerary){
return itinerary.endDate.split('T').slice(-1)[0]
}
and call like
{itinerary.name} from {getStartDateFromstring(itinerary)} to {getEndDateFromstring(itinerary)}
I got it working with this
function addZeroIfOnlyOneChar(dateString){
dateString = String(dateString);
if(dateString.length < 2){
return '0' + dateString
}
return dateString
}
function getDateFromString(dateString){
const date = new Date(dateString)
const day = date.getDate();
const month = date.getMonth() + 1;
const year = date.getFullYear();
return `${addZeroIfOnlyOneChar(day)}-${addZeroIfOnlyOneChar(month)}-${year}`
}
Thanks Everyone

Moment.js is converting Date to Today date using React Big Calendar

I've got a problem where the date is being converted to today's date even though the date is being parse by moment. It looks like Moment is converting the date to today's date. I believe I am just using the script incorrectly. I'm not familiar with Moment. Any help would be appreciated.
export function getEvents (callback) {
request
.get(url)
.end((err, resp) => {
if (!err) {
const events = [];
JSON.parse(resp.text).items.map((event) => {
events.push({
start: moment(event.start.date).toDate()|| moment(event.start.dateTime),
end: moment(event.end.date).toDate() || moment(event.end.dateTime),
title: event.summary,
})
});
callback(events)
}
})
This is an example of the trace where the "start" date from Google Calendar is in a Timeformat.
This is the conversion and a trace of the script
Here is the date in real time on the call:
The issue that fixed this is in the Moment api. Use this :
JSON.parse(resp.text).items.map((event) => {
var start = moment(event.start.dateTime,'YYYY-MM-DD HH:mm').toDate();
var end = moment(event.start.dateTime,'YYYY-MM-DD HH:mm').toDate();
events.push({
start: start,
end: end,
title: event.summary,
})
});
After looking into your resp.text that provided in comments I created the following parse method to parse your response as the way you wanted.
Here response passed to this method is your resp.text which you supplied in comments.
import moment from 'moment'
const parseResponse = (response) => {
const events = []
response.forEach(obj => {
obj.items.forEach(
item => {
events.push({
start: moment(item.start.dateTime),
end: moment(item.end.dateTime),
title: item.summary
})
}
)
})
return events
}
Note: Check the codesandbox.io/s/ywpznzrmv9 pen if you want to look into moment workaround. You can get rid of first forEach block if the resp.text is having only one array of object.|
like:
const parseResponse = (response) => {
const events = []
response[0].items.forEach(
item => {
events.push({
start: moment(item.start.dateTime),
end: moment(item.end.dateTime),
title: item.summary
})
}
)
return events
}
Note: If you stick to using JSON.parse() then change map to forEach. map creates an object, which is a garbage that you won't need in your case.

Functions in React: my function isn't working, because of 'read-only' error. Why?

I'm trying to write a function into a React component, but I am stuck with this error:
Uncaught Error: Module build failed: SyntaxError: "productMap" is read-only
Why is this happening? And how can I fix this, so I can use productMap?
Here is my function:
printReceipt() {
var products = this.props.updateBasket.products;
//create a map of products
const productMap = {};
for(let product of products) {
if(!productMap[product.id]) {
productMap[product.id] = 1;
} else {
productMap = productMap + 1;
}
}
console.log(productMap);
}
This is happening because poductMap is of type const and const cannot change through reassignment
Change it to a let or var instead
printReceipt() {
var products = this.props.updateBasket.products;
//create a map of products
let productMap = {};
for(let product of products) {
if(!productMap[product.id]) {
productMap[product.id] = 1;
} else {
productMap = productMap + 1;
}
}
console.log(productMap);
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
Use let productMap={}; instead of const.
The const declaration creates a read-only reference to a value.
Reference
use ()=> FunctionName() instead of FunctionName()
When we call the function FunctionName(), it is just executed, but when we write () => FunctionName(), then it is only called when that particular operation is performed for example onPress.
FunctionName() sometimes doesn't work, and is only read-only, using () => FUnctionName, is a good way.

how to display Json Formated Datetime in angularJs

how to display Json datetime formate in angularJs its showing Datetime as"/Date(820434600000)/"
Angular Code
app.controller("MyDeptCntrl", function ($scope, MyDeptSer) {
$scope.BtnDept = function () {
var Dept = MyDeptSer.GetDeptData();
Dept.then(function (d) {
$scope.DeptData = d.data;
// $filter('date')(date, format, timezone)
},function(e){
alert('Loading Failed....')
})
}
use below function to parse the date first
function dateParser(input){
input = input.replace('/Date(', '');
return new Date(parseInt(input,10));
}
so
$scope.DeptData = dateParser(d.data);
You can try this
convertJsonDateTimeToJs: function (jsonDate) {
var dateSlice = jsonDate.slice(6, 24);
var milliseconds = parseInt(dateSlice);
return new Date(milliseconds);
}
I'd recommend changing your server side code to use a friendlier JSON serializer but if not, try:
// You start with /Date(820434600000)/
// substr(6) takes off the /Date( part and pass the number 820434600000 into the parseInt function.
// Note: the parseInt function will ignore the )/ and the end.
var friendlyDate = new Date(parseInt($scope.DeptData.someDateMember.substr(6)));
// Then, you can format it using angular date filter -- for example:
$scope.formattedDate = $filter('date')(friendlyDate, 'MM/dd/yyyy');

Resources