How do I render an object in react native? - arrays

Working on pulling data from an external API (FlightStats).
Currently the data fetch is working as it finds the childs of the parent request. Now stuck rendering through an array problem.
Tried multiple options for the request and data source options
Request from API:
componentDidMount() {
fetch('https://api.flightstats.com/flex/schedules/rest/v1/json/flight/AA/100/departing/2019/3/24?appId=XXXXX&appKey=+XXXXX')
.then((response) => response.json())
.then((response) => {
this.setState({
request: response.request
})
})
.catch((error) => {
console.log(error)
});
}
Constructor:
constructor() {
super();
this.state = {
request: 'carrier'
}
}
Render:
<View style={Global.container}>
<Text>{this.state.request.carrier}</Text>
{/* //={[{ key: 'a'}, { key: 'b'}]}
//renderItem={({item }) => <Text>{item.key}</Text>} */}
</View>
Data result in Json
{"request":{"carrier":{"requestedCode":"AA","fsCode":"AA"},"codeType":{},"flightNumber":{"requested":"100","interpreted":"100"},"departing":true,"date":{"year":"2019","month":"3","day":"24","interpreted":"2019-03-24"},"url":"https://api.flightstats.com/flex/schedules/rest/v1/json/flight/AA/100/departing/2019/3/24"},"scheduledFlights":[{"carrierFsCode":"AA","flightNumber":"100","departureAirportFsCode":"JFK","arrivalAirportFsCode":"LHR","stops":0,"departureTerminal":"8","arrivalTerminal":"3","departureTime":"2019-03-24T19:40:00.000","arrivalTime":"2019-03-25T06:50:00.000","flightEquipmentIataCode":"77W","isCodeshare":false,"isWetlease":false,"serviceType":"J","serviceClasses":["R","F","J","Y"],"trafficRestrictions":[],"codeshares":[{"carrierFsCode":"AY","flightNumber":"4012","serviceType":"J","serviceClasses":["F","J","Y"],"trafficRestrictions":[],"referenceCode":1139031},{"carrierFsCode":"BA","flightNumber":"1511","serviceType":"J","serviceClasses":["R","F","J","Y"],"trafficRestrictions":[],"referenceCode":1250367},{"carrierFsCode":"GF","flightNumber":"6654","serviceType":"J","serviceClasses":["J","Y"],"trafficRestrictions":["Q"],"referenceCode":2204628},{"carrierFsCode":"IB","flightNumber":"4218","serviceType":"J","serviceClasses":["R","F","J","Y"],"trafficRestrictions":[],"referenceCode":2305895},{"carrierFsCode":"LY","flightNumber":"8051","serviceType":"J","serviceClasses":["F","J","Y"],"trafficRestrictions":["Q"],"referenceCode":2942513}],"referenceCode":"807-470028--"}],"appendix":{"airlines":[{"fs":"AA","iata":"AA","icao":"AAL","name":"American Airlines","phoneNumber":"08457-567-567","active":true},{"fs":"LY","iata":"LY","icao":"ELY","name":"El Al","phoneNumber":"+ 972-3-9771111","active":true},{"fs":"AY","iata":"AY","icao":"FIN","name":"Finnair","phoneNumber":"+ 358 600 140 140","active":true},{"fs":"IB","iata":"IB","icao":"IBE","name":"Iberia","phoneNumber":"1800 772 4642","active":true},{"fs":"BA","iata":"BA","icao":"BAW","name":"British Airways","phoneNumber":"1-800-AIRWAYS","active":true},{"fs":"GF","iata":"GF","icao":"GFA","name":"Gulf Air","phoneNumber":"973 17 335 777","active":true}],"airports":[{"fs":"JFK","iata":"JFK","icao":"KJFK","faa":"JFK","name":"John F. Kennedy International Airport","street1":"JFK Airport","city":"New York","cityCode":"NYC","stateCode":"NY","postalCode":"11430","countryCode":"US","countryName":"United States","regionName":"North America","timeZoneRegionName":"America/New_York","weatherZone":"NYZ178","localTime":"2019-03-24T00:55:59.327","utcOffsetHours":-4.0,"latitude":40.642335,"longitude":-73.78817,"elevationFeet":13,"classification":1,"active":true},{"fs":"LHR","iata":"LHR","icao":"EGLL","name":"London Heathrow Airport","city":"London","cityCode":"LON","stateCode":"EN","countryCode":"GB","countryName":"United Kingdom","regionName":"Europe","timeZoneRegionName":"Europe/London","localTime":"2019-03-24T04:55:59.327","utcOffsetHours":0.0,"latitude":51.469603,"longitude":-0.453566,"elevationFeet":80,"classification":1,"active":true}],"equipments":[{"iata":"77W","name":"Boeing 777-300ER","turboProp":false,"jet":true,"widebody":true,"regional":false}]}}
Error Message:
Invariant Violation: Objects are not valid as a React child (found: object with keys {resquestedCode, fsCode}). If you meant to render a collection of childen, use an array instead.
So this is where I am stuck. The initial fetching is working and finding the sub children. For some reason not sure why I cannot render the items or just display the results from the json.
Any help or tutorials will do.
Thanks again

carrier is an object in your JSON data and hence you cannot print it directly. If you want to print it as a string, please do this.
<Text>{JSON.stringify(this.state.request.carrier)}</Text>
If you want it to look neat, you can format it like this.
<Text>{JSON.stringify(this.state.request.carrier, 0, 4)}</Text>

Related

Cannot read properties of undefined (reading 'data') in React - Comment Section

I am implementing a comment section. I am reading the data that is being saved in a database. However when reading the comments from an array of comments its giving issue on this line
const message_list =response.data.results.data.message.map((value) => (value));
Ive taken the code from this
https://riyanegi.github.io/react-comments-documentation/
axios.get( process.env.REACT_APP_API_URL +"product/" + this.product_id +"/idea/"+ this.idea_id +"/comment",{
headers: {
Authorization: "Bearer "+ user_access_token,
}})
.then(response => {
const message_list =response.data.results.data.message.map((value) => (value));
this.setState({ data: [...this.state.data, ...message_list] });
});
And then I am rendering:
render() {
return <CommentSection
currentUser={{
currentUserId: this.currentUser.user,
currentUserImg:
'https://ui-avatars.com/api/name='+this.currentUser.name+ '&background=random',
currentUserFullName: this.currentUser.name
}}
commentData={this.state.data}
onSubmitAction={(data) => this.onSubmitAction(data)}
onEditAction={(data) => this.onEditAction(data)}
onDeleteAction={(data) => this.onDeleteAction(data)}
customNoComment={() => this.customNoComment()}
onReplyAction = {(data)=>this.onReplyAction(data)}
/>
}
Based on the console.log you provided, it appears that response.data.results.data may need to be just response.data. You can confirm this by checking the console output to ensure that message is a property on it, and results isn't.
In any case, if you examine the object in your console to find the message array that you're trying to map, you should be able to find your message array nested somewhere in there.

Firebase Error: Objects are not valid as a React child (found: object with keys {seconds, nanoseconds})

First I query for my data from firebase:
useEffect(() => {
if (user) {
async function fetchData() {
const request = await db
.collection("users")
.doc(user)
.collection("notifications")
.onSnapshot((snapshot) =>
setNotifications(
snapshot.docs.map((doc) => ({ ...doc.data(), id: doc.id }))
)
);
}
fetchData();
} else {
setNotifications([]);
}
}, [user]);
The query returns this:
Now, when I try to render the data:
<div className="notifications">
{notifications.map((notification) => (
<NotificationContainer
notificationType={notification.notificationType}
notificationFrom={notification.notificationFrom}
timestamp={notification.timestamp}
linkId={notification.linkId}
/>
))}
When I try to render the data on the page, I get the following error:
Error: Objects are not valid as a React child (found: object with keys {seconds, nanoseconds}). If you meant to render a collection of children, use an array instead.
Any idea what I am doing wrong? I think there may be something wrong in the day I am reading the data from my notifications array
Short answer is somewhere in your code, you're trying to render object.
Something like this will give you that error "Object are not valid React Child"
const obj = { a: 1 }
const SomeComponent = () => {
return (
<div>{obj}</div>
)
}
In your case, I assume "notification" is an object that look like this, firebase return timestamp in object format
notification: {
timestamp: {
seconds: 1700000000,
nanoseconds: 1700000000000,
}
}
Thus in must have somewhere that try to render this object
return (
...
<div>{timestamp}</div>
...
)
If you find this and change to
return (
...
<div>{timestamp.seconds}</div>
...
)
Should make the error disappear.
So I was using the timestamp firebase field. And when I tried to render it, the nasty error I was talking about pops up.
The timestamp is not a string and most likely an object.

React not rendering component after componentDidMount

I have an Component, which is no rerendering after componentDidMount.
The render Method is looking like this :
render() {
{
console.log("----------RENDERING-----------------------------")
}
return (
<ImageBackground
source={require('../assets/images/bg.png')}
style={styles.bg}
>
<View style={styles.containerHome}>
<View style={styles.top}>
<City/>
<Text>myapp</Text>
{/*<Filters />*/}
</View>
<CardStack
loop={true}
verticalSwipe={false}
renderNoMoreCards={() => null}
ref={swiper => (this.swiper = swiper)}
>
{this.state.data.map((item, index) => (
<Card key={index}>
<CardItem
text={item.name}
detail={item.detail}
imageurl={item.imageurl}
matches="0"
actions
onPressLeft={() => this.swiper.swipeLeft()}
onPressRight={() => this.swiper.swipeRight()}
/>
</Card>
))}
</CardStack>
</View>
</ImageBackground>
);
}
...simply rendering a card stack.
Relevant here is this line :
this.state.data.map((item, index) => (
If i set the Data static from a file (Demo), it is working!
means if the line is looking like this
Demo.map((item, index) => (
everything alright!
but when i set the data in componentDidMount, it is not working!
I really dont know what react-native is doing here :
componentDidMount() {
this.setState({
isLoaded: true,
data: Demo
});
I set the state.data to exactly the same Demo Values, but react is not rerendering.
It seems to be that this.state.data is always empty.
Maybe anyone can help me?
Thx so much
ComponentDidMount() executes after the render() function, so you had better do this before rendering and outside of ComponentDidMount():
this.setState({
isLoaded: true,
data: Demo
});
So initially, before render(), you have to set some value of data.
Try with three possible answers:
Default value {data:Demo}, or
Implement this.state in a function which can be executed before render(), or
Put it in the render() function before the return statement.
Thx so much for the hint.
But i have already problems. Seems that i dont get the lifecylce, even when i am programming now react for a liitle bit.
Your hint was excellent, when i do it in the constructor, it is working.
But in the end, i wann fetch the data there, and if i do this, it doesnt seems to work in the constructor.
fetch('http://hostname/api/v1/xxxx', {
method: 'get',
headers: new Headers({
'Authorization': 'Bearer pumuckl',
'Content-Type': 'application/json'
}
)
}).then(res => res.json())
.then(
(result) => {
this.state = {
data: Demo,
}
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
the code is from the facebook documentation! Fetch is working!
What i am doing here is setting the state to the Demo Data, just to see if the lifecylce is waiting for the constructor and it seems that it doesn't.
Seems that rendering is be triggered before the constructor has finished initializing (..i can not imagine, that would be really bad), but i get a null Exception in the List!
Do i have to work with async await? I dont think so.
Just wanna initialze my List before rendering from a fetch.
Absolutely strange.
so if you look in my logs how the lifecycle is processing :
10-28 17:44:06.847 4796 5362 I ReactNativeJS: *************************** Constructor *****************************************************
10-28 17:44:06.851 4796 5362 I ReactNativeJS: ----------RENDERING-----------------------------
10-28 17:44:06.918 4796 5362 I ReactNativeJS: *************************** component Did Mount *****************************************************
10-28 17:44:06.927 4796 5362 I ReactNativeJS: ----------RENDERING-----------------------------
10-28 17:44:06.935 4796 5362 I ReactNativeJS: *************************** component Did Update *****************************************************
I am really a little bit desperate at the moment....
when i log my data in the rendering method :
render() {
const data = this.state.data
{
console.log("----------RENDERING-----------------------------")
console.log("----------DATA IN RENDERING-----------------------------")
console.log(data)
}
return ( ...
actually, the data seem be there. But using
{data.map((item, index) => (
does not work, while
{Demo.map((item, index) => (
is working.
I really dont know what going on here?

Error while rendering an array from firestore to react native

i have an array that i am trying to read and store in a state however, with the code below, here is the error i get: "function collectionReferenace.doc() requires its first argument to be of type non-empty string, but it was undefined" any idea why this is happening and what is the solution?
componentDidMount(){
dbh.collection('Groups').doc(this.props.route.params.groupName)
.collection('Enrolled').doc('ids').get()
.then(querySnapshot => {
querySnapshot(doc => {
this.setState({
playerIDs: doc.data().players
})
})
})
console.log(this.state.playerIDs)
}
the this.props.route.params.groupName is passed from the navigation of the previous screen. When I set a constant in the render function to it and call that variable it works fine.
render() {
const groupName = this.props.route.params.groupTitle
return
<Text>{groupName}</Text>
for your reference, here is how i am getting that route.param
<GroupComponent onPress = {
() => this.props.navigation.navigate
('Attendance', {groupTitle: group.GroupName, groupID: group.id})
} />
Based on your code, you should be acccessing dbh.collection('Groups').doc(this.props.route.params.groupTitle) not groupName. The object you pass through params has keys groupTitle and and groupID, not groupName.

How to get data from API and turn it into array list for Google Charts

I'm pretty new to React and am currently trying to use the Nasa neo API to feed data into a react google chart.
The problem is when i send a get request with axios i end up with loads nested data objects that i somehow have to convert to a array to use with google charts.
class MainPage extends Component {
state = {
data: [['name', 'max estimated diameter', 'min estimated diameter']]
};
componentDidMount() {
axios
.get('https://api.nasa.gov/neo/rest/v1/neo/browse?api_key=DEMO_KEY')
.then(response => {
this.setState({ data: response });
})
.catch(function(error) {
console.log(error);
});
}
}
this is what i have so far, i'm guessing i need to map through the data but everything i've tried so far doesn't seem to work.
anyone know how i should proceed ?
or got any pointers ?
Since you're using Axios, your get request will return an object with data key.
.then(({data}) => { // destructure data from response object
// {name, estimated_diameter} from data
const restructuredData = data.near_earth_objects.map(({name, estimated_diameter}) =>
[name, estimated_diameter.metrics. estimated_diameter_max, estimated_diameter.metrics.estimated_diameter_min])
this.setState({data: restructuredData});
})
.catch(function (error) {
console.log(error);
})
Axios response schema for your reference https://github.com/axios/axios#response-schema
From the swagger documentation I can see that the endpoint /neo/browse returns something like this:
{
"is_potentially_hazardous_asteroid": true,
"is_sentry_object": true,
"neo_reference_id": "string",
"name": "string",
"name_limited": "string",
"designation": "string",
"nasa_jpl_url": "string",
"absolute_magnitude_h": 0,
"estimated_diameter": {},
"close_approach_data": [
{
"close_approach_date_full": "string",
"close_approach_date": "string",
"epoch_date_close_approach": 0,
"relative_velocity": {},
"miss_distance": {},
"orbiting_body": "string"
}
],
"orbital_data": {},
"sentry_data": "string"
}
This is a JSON so what you want to do is getting the fields and then save them in your state.
From the google react chart api I see we want data to be an array of arrays, like this:
const data = [
["Column1", "Column2"],
["row1_column1", "row1_column2"],
["row2_column1", "row2_column2"],
// ...
];
What I would do is:
.then(response => {
this.state.data
this.setState({
data: [
...this.state.data
[
response.data.name,
response.data.estimated_diameter.kilometers.estimated_diameter_max,
response.data.estimated_diameter.kilometers.estimated_diameter_min
]
]
})
Basically we are appending a new array with the three values we want to the already existing data. To extract the values from the JSON we have received from the API we just need to look at the response we receive by trying out the API on swagger.
Also remember that setState() is asynchronous.
This answer will help you...
<Chart
data={[
['column1', 'column2', 'column3'],
...array.map(d => [ d.column1, d.column2, d.column3 ])
]}
/>

Resources