Objects are not valid as React child - reactjs

I have a function which calculates the date from a unix timestamp
_getTime(time) {
var dateTime = new Date(time*1000);
console.log(dateTime);
return dateTime
},
The function is used in this
render: function() {
return (
{this.state.daily.map(day => {
return (
<div key={day.time} className="key col-md-12">
<div className="col-md-3">{this._getTime(day.time)}</div>
</div>
);
);
},
This returns Invariant Violation: Objects are not valid as a React child (found: Thu Oct 20 2016 00:00:00 GMT+0200 (CEST)). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method ofApp.
I am aware of there questions with the same error message, but I can't seem to figure out a solution for my problem.

Plain javascript:
_getTime(time) {
var dateTime = new Date(time*1000).toString();
console.log(dateTime);
return dateTime
},
Using moment.js
_getTime(time) {
var dateTime = moment(time*1000).format('YYYY-MM-DD HH:mm:ss');
console.log(dateTime);
return dateTime
},

Related

PrimeNg 12 p-calendar UTC issue

I've a problem with PrimeNg Calendar component. I need to remove UTC from selected value in calendar. Selecting a date in the calendar component, the form value is:
Wed Jun 01 2022 00:00:00 GMT+0200 (Ora legale dell’Europa centrale)
so when i call a rest service passing this value, it is converted into:
"2022-05-31T22:00:00.000Z"
I know it's a problem related to UTC but I can't find a way to remove UTC setting attributes into p-calendar.
Is there a way to do this? Or it's possibile to manage the selected value into a directive?
I'm using PrimeNg 12.2.16
For me I made a solution with a directive and date offset correction:
import { Calendar } from 'primeng/calendar';
import { Directive } from '#angular/core';
#Directive({
selector: '[utcCalendar]',
})
export class UtcCalendarDirective {
constructor(private pCalendar: Calendar) {
// Function was taken from
// https://github.com/primefaces/primeng/blob/master/src/app/components/calendar/calendar.ts
pCalendar.updateModel = (value) => {
pCalendar.value = value;
if (pCalendar.dataType == 'date') {
// Changes
const date = new Date(pCalendar.value);
date.setTime( date.getTime() + (-date.getTimezoneOffset())*60*1000 );
pCalendar.onModelChange(date);
}
else if (pCalendar.dataType == 'string') {
if (pCalendar.isSingleSelection()) {
pCalendar.onModelChange(pCalendar.formatDateTime(pCalendar.value));
}
else {
let stringArrValue = null;
if (pCalendar.value) {
stringArrValue = pCalendar.value.map((date: any) => pCalendar.formatDateTime(date));
}
pCalendar.onModelChange(stringArrValue);
}
}
};
}
}
And then when I do value.toISOString() It will give a date like '2022-09-12T00:00:00.000Z'.
Tested with forms. Outputs like onSelect() and some other functionality won't be changed but you can improve this code.

Why do I get "RangeError: date value is not finite in DateTimeFormat format()" when using Intl.DateTimeFormat in React?

I cannot see where the date format is being passed incorrectly to cause the RangeError?
I don't seem to be able to parse user.created. The user details are being brought in from a json response in reality, but I've shown them as a variable in this example.
Here's my MRE:
import * as React from "react";
function Details() {
const user = {
firstName: "Anthony",
created: "2020-08-19T23:13:44.514Z",
updated: "2020-09-12T00:31:31.275Z"
};
const userJoined = new Intl.DateTimeFormat("en-GB", {
year: "numeric",
month: "long",
day: "2-digit"
}).format(user.created.toString());
return (
<div>
<p>{user.firstName}</p>
<p>
Joined:
{new Intl.DateTimeFormat("en-GB", {
year: "numeric",
month: "long",
day: "2-digit"
}).format(userJoined)}
</p>
</div>
);
}
export { Details };
You may need to parse the string to date.
const user = {
firstName: "Anthony",
created: new Date("2020-08-19T23:13:44.514Z"),
updated: new Date("2020-09-12T00:31:31.275Z")
};
You get this when you pass an invalid date to format(). Make sure it is a Date().
import moment from "moment-timezone";
moment.utc(date).tz(browserTimezone).format();
I know most of these issues have been resolved in modern versions of browsers, but I just ran into a case where this error was caused by having milliseconds attached to the end of my dates like this --
'2022/10/25 11:22:42.570684', // .570684
This works well in Chrome but not in any other browser i.e. Safari.
After removing the milliseconds
'2022/10/25 11:22:42', // Works as expected, no milli seconds.
a link to the docs https://dygraphs.com/date-formats.html

Why is this date sum not being displayed correctly in react?

I have the following component which simply gets the current date, adds a year to it, and should render it. But its rendering a weird number
import React from 'react'
class Calendario extends React.Component {
constructor(props) {
super(props);
this.state = {
birth_date : new Date(),
years_to_live: 10,
death_date: ""
};
}
componentDidMount() {
var death_date = this.state.birth_date.setFullYear(this.state.birth_date.getFullYear() + 1) //this is should result in the current date +1
this.setState({ death_date : death_date});
}
render() {
return (
<div>
<p>Hello world!</p>
<p>{this.state.death_date}</p>
</div>
)
}
}
export default Calendario;
It for some reason renders
1610227797517
Instead of
Sat Jan 09 2021 22:21:12 GMT+0100 (Central European Standard Time)
Whats the issue?
You are getting back a date as an integer, since you are using a javascript Date object for birth_date.
You can parse it back to a date to do what you need to (format, etc.)
var dt = new Date(1610227797517);
console.log(dt);
// output: Sat Jan 09 2021 16:29:57 GMT-0500 (Eastern Standard Time)
But, you should be able to use a format on the object itself
console.log(this.state.death_date.toDateString());
// output: Sat Jan 09 2021

relative time in redux reactjs

I have some data with datetime fields , i want to show the relative date time using momentJS fromNow(). However after the initial load it shows timestamp as a few seconds ago. But this will not be updated until a next state change triggered. Is it a good practice to keep another state in the state-tree & control via a timer function setInterval in componentDidUpdate?
render()
{
// get the new prop value here which triggered from a setInterval -> action -> reducer -> state change -> propagate to connected components
const text = comment.get('text');
const dateTime = moment(comment.get('dateTime')).fromNow();
return (
// add the new prop into the component
<div key={id}>
<Comment
text = {text}
dateTime = {dateTime}
</div>
}
I scribbled down a component that takes an epoch time timestamp and display a momentjs text for it.
The text is updates via inner component state every 300ms which you can change however you'd like.
You can notice on this fiddle, every new text is logged in the console. After 45 seconds you should see the text change from "a few seconds ago" to "a minute ago".
Fiddle here, this is the code:
var MomentTime = React.createClass({
getInitialState: function() {
return {text: ""};
},
componentWillMount: function() {
this._updateMomentText();
this.interval = setInterval(this._updateMomentText, 300);
},
componentWillUnmount: function() {
clearInterval(this.interval);
},
_updateMomentText: function() {
var text = moment(this.props.timestamp).fromNow()
console.log(text)
if(text !== this.state.text) {
this.setState({text: text});
}
},
render: function() {
return <div>{this.state.text}</div>;
}
});
ReactDOM.render(
<MomentTime timestamp={new Date().getTime()} />,
document.getElementById('container')
);

Getting the warning from chrome dev tools that each child should have a unique key prop

I'm learning Reactjs and tried to copy the example from this facebook git, children to make the warning disappear, but I'm still getting it:
var MyComponent = React.createClass({
getInitialState: function () {
return {idx: 0};
},
render: function() {
var results = this.props.results;
return (
<ol>
{results.map(function(result) {
return <li key={result.id}>{result.book}</li>;
})}
</ol>
);
}
});
var result = [
{title: "book", content: "booky"},
{title: "pen", content: "penny"},
];
document.addEventListener("DOMContentLoaded", function () {
ReactDOM.render(<MyComponent results={results} />, document.getElementById('widgets'));
});
A few things going on here that need to be rectified:
The variable you're declaring and assigning the array of results to is named result but you are passing a variable named results as the results prop to MyComponent. Rename this variable to results.
The two object properties you're attempting to access on the result object inside the map function are id and book, neither of which are defined on the object itself (title and content are). Change {result.book} to {result.title} in this case.
Finally, in order to supply a unique ID to each element returned from the map, set the second parameter of your map (e.g. results.map(function(result, i) {... and use the array index as your unique key.
In summary:
results.map(function(result, i) {
return <li key={i}>{result.title}</li>;
})

Resources