Render array of objects React - javascript

My local JSON file is as follows
[
{ "time": "2017", "Id": 1, "value": 40 },
{ "time": "2018", "Id": 1, "value": 65 },
{ "time": "1018", "Id": 1, "value": 34 }
]
I imported the JSON like:
import * as readings from '../data/readings';
And I want to render my data in a list in a React component.
This is what I have been tried:
import * as readings from '../data/readings';
class Table extends Component {
render (){
const data = Object.keys(readings).map((row, index) =>
<li key={index}> {row} </li>);
return (
<div>
<ul>
{data}
</ul>
</div>
);
}
}
export default Table;
After rendering this component, I will see "default" on the screen but my aim is to have each object in one row like:
"time": "2017", "Id": 1, "value": 40
"time": "2018", "Id": 1, "value": 65
"time": "1018", "Id": 1, "value": 34
Can someone tell me what I am doing wrong?
I've read a lot of related question but I could not relate.
Edit:
My data is an array itself but the import gives it like an object. That's why I use Object.keys and not readings.map

readings is itself an array so that is what you want to map over: readings.map(). The items in it are the objects you want to display, so there is where you want to use Object.keys(). Since you want to use the values as well, Object.entries() is slightly more readable.
Also, you are importing data from a JSON file so you should import the data as though it was a default export. You should explicitly specify the .json file type since it is not a .js file.
import readings from '../data/readings.json';
class Table extends Component {
render() {
const data = readings.map((reading, index) => {
const readingData = Object.entries(reading).map((k, v) => <span>{k}: {v}</span>);
return <li>{readingData}</li>;
};
return (
<div>
<ul>
{data}
</ul>
</div>
);
}
}
export default Table;

Your readings is not an object, it's an array! So, what you should do is to iterate over it, and for every inside object, do the process of Object.keys(readings).map()
import * as readings from '../data/readings';
class Table extends Component {
render (){
const data = readings.map((row, index) =>
<li key={index}>
{
Object.keys(row).map(e =>
`${e[0]: e[1],} `
}
)
</li>
)
return (
<div>
<ul>
{data}
</ul>
</div>
);
}
}
export default Table;

Your readings data is already an Array. You can directly use map on it.
import * as readings from '../data/readings';
class Table extends Component {
render (){
const readingsArray = Object.keys(readings).map(key => readings[key]);
const data= readingsArray.map(obj => <li>{JSON.stringify(obj)}</li>);
return (
<div>
<ul>
{data}
</ul>
</div>
);
}
}
export default Table;

Related

Is it nessesary to use getStaticProps with json import in Next.js?

I want to render static data that is coming from a JSON or typescript file and display it to the user. Do I have to use getStaticProps or can I simply import the data without getStaticProps? It's not clear to me after reading the next documentation.
projects.tsx
const projects: [
{
id: "6853939";
name: "Project 01";
title: "Title 01 ";
previewImg: "/images/projectThumbnails/image01.jpg";
},
{
id: "6853939";
name: "Project 02";
title: "Title 02 ";
previewImg: "/images/projectThumbnails/image02.jpg";
}
];
export default projects;
names.json
{
"names": [
{ "name": "Full Name 01", "age": 34 },
{ "name": "Full Name 02", "age": 22 },
],
}
index.tsx
import projects from "../data/projects.tsx";
import names from "../data/names.json";
const IndexPage = () => {
return (
<>
<div>
{projects.map((i) => (
<div key={i.id}>{i.title}</div>
))}
</div>
<div>
{names.names.map((i) => (
<div key={i.name}>{i.name}</div>
))}
</div>
</>
);
};
It's totally up to you which approach you are going to use .
With getStaticProps:
server uses JSON data to inject data and create cache
Without getStaticProps:
JSON file would be injected in client side , without being cached
I prsonally recommend using getStaticProps
Importing JSON in getStaticProps:
import yourJson from ('./somefile.json')
export async function getStaticProps(context) {
//use your json here
return {
props: {}, // will be passed to the page component as props
}
}

Error: Objects are not valid as a React child. If you meant to render a collection of children, use an array instead. Getting data from JSON

guys! I'm using ReactJS to create a small website. Since I added the following code it starts showing an error: Objects are not valid as a React child. If you meant to render a collection of children, use an array instead.
Code:
import { useState, useEffect } from 'react';
import { motion, useAnimation } from 'framer-motion';
import './css/App.min.css';
import config from './config';
function App() {
return (
<div className="myskills">
<Skills skillType="coding" />
</div>
);
}
function Skills(props){
const skillType = props.skillType;
const result = config.skills.filter(skill => skill.cat == skillType);
console.log(result);
result.map((skill, index) => (
<div className="singleSkill" key={index}>
{skill.name} Level: {skill.level}
</div>
));
return (<div>{result}</div>);
}
config.json
{
"skills": [
{
"name": "HTML",
"level": 5,
"cat": "coding"
},
{
"name": "CSS",
"level": 5,
"cat": "coding"
},
{
"name": "PHP",
"level": 4,
"cat": "coding"
}
]
}
Any ideas what's the problem?
The return statement in your Skills component is basically just this:
return (config.skills.filter(skill => skill.cat == skillType));
hence the "Objects are not valid as a React child" error.
Since result.map doesn't modify the original array, a better solution might look something like this:
function Skills(props) {
const skillType = props.skillType;
const result = config.skills.filter(skill => skill.cat == skillType);
return (
<div>
{result.map((skill, index) => (
<div className="singleSkill" key={index}>
{skill.name} Level: {skill.level}
</div>
))}
</div>
);
}

How to access nested JSON graphql object passed into react child component, then list those items?

GraphQL:
{
"data": [
"theProducts": {
"id": "1",
"name": "Fitness bands",
"resistanceLevels": {
"UltraHeavy": 10,
"Heavy": 8,
"Medium": 6 },
"prices": [
16.8,
24.9
13.2
]
}
]
}
I am trying to get the resistanceBands JSON object and the price array to map to the react child component (the query is defined in the parent component) and render the items in a list with bullet points.
Parent Component:
const GET_PRODUCT_DATA = gql`
query getProducts {
theProducts {
id
name
resistanceLevels
prices
}
}
`
// How I am mapping data (name, etc) into the child component
const productsToRender = data.theProducts
{productsToRender.map( product => <ProductDisplay key={product.id} product={ product } />) }
// How can map the object and array to display their items to the ProductDisplay child component?
Child Component:
<div>
<h1>{product.name}</h1> // This works
<p>Resistance Levels | Intensity:</p>
<ul>
<li>{product.resistanceLevels}</li> // This doesnt
</ul>
<p>Prices</p>
<ul>
<li>{product.prices}</li> // This doesnt
</ul>
</div>
You need to use .map() for prices also because that's an array as:
<ul>
{product.prices.map(p => <li>{p}</li>)}
</ul>
Also for resistanceLevels you can use Object.keys and .map() combination as:
const resistanceLevels = {
"UltraHeavy": 10,
"Heavy": 8,
"Medium": 6
};
const result = Object.keys(resistanceLevels)
.map(k => resistanceLevels[k]);
console.log(result);
Read from the documentation:
The Object.keys() method returns an array of a given object's own enumerable property names, iterated in the same order that a normal loop would.
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
I guess this gives you the idea how to move further based on the example of prices.map().
const ParentComponent =()=>{
return(
<div>
{productsToRender.map(product => <ProductDisplay key={product.id} product={product }/>) }
</div>
)
}
export default ParentComponent;
const ProductDisplay =(props)=>{
return (
<div>
<h1>{product.name}</h1>
<p>Resistance Levels | Intensity:</p>
<ul>
{Object.entries(props.product.resistanceLevels).map(([key, value]) =>{
return(
<li>{key} : {value}</li>
)
})}
</ul>
<ul>
{
props.product.prices.map(item => {
<li>{item}</li>
})
}
</ul>
</div>
)
}

Unable to display API call result to WebPage

I have react App.js page from where i am calling Django Rest API and i am getting response as an array now this array i have nested components and i want that nested component to be listed in my code.
If i can showcase single record given by single person name when i try to do with more than one i am getting following error.
Warning: Each child in an array or iterator should have a unique "key" prop.
Now if i change API URL as below
https://e2isaop.rokuapp.com/api/perns/1
I can able to view data in HTML but when it comes to all persons it fails.
I am sorry i am new react not sure how to iterate over sub array of result.
Kindly guide me here for best practice for this.
Here is API Response in JSON
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"uri": "/api/Persons/1",
"PersonId": 1,
"PersonName": "Nirav Joshi",
"Person_Image": "https://ja.amazonaws.com/media/persons/None/51e1257926f3cb184089c41fa54b8f8e1b65a98f1e35d39e55f2b6b335e83cf4.jpg",
"Person_sex": "M",
"Person_BDate": "2019-04-19",
"Person_CDate": "2019-04-23"
},
{
"uri": "/api/Persons/2",
"PersonId": 2,
"PersonName": "New Joshi",
"Person_Image": "https://ja.amazonaws.com/media/persons/None/cc08baaad2ccc918bc87e14cac01032bade23a0733b4e313088d61ee78d77d64.jpg",
"Person_sex": "F",
"Person_BDate": "2011-11-21",
"Person_CDate": "2019-04-27"
},
]
}
Here is react App.js code.
import React from "react";
import ReactDOM from "react-dom";
import Persons from "./Persons";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
persons: []
};
}
componentDidMount() {
fetch("https://e2isen.okuapp.com/api/psons/")
.then(response => response.json())
.then(data => {
let apipersons;
if (data.isNull) {
apipersons = [];
} else {
apipersons = [data];
console.log(apipersons);
}
this.setState({ persons: apipersons });
});
}
render() {
return (
<div>
<h1>Welcome to PersonAPI</h1>
<div>
{this.state.persons.map(pers => {
return (
<Persons
PersonName={pers.PersonName}
key={pers.PersonId}
Person_Image={pers.Person_Image}
Person_BDate={pers.Person_BDate}
Person_sex={pers.Person_sex}
/>
);
})}
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
It should give me result for Four person with their details
PersonName
PersonImage
PersonBdate
PersonSex
You should do :
// apipersons = [data];
apipersons = data.results

Each child in an array or iterator should have a unique "key" prop in reactjs

I totally confused, because I have mistake in my console and I read reactjs documentation and all tips on stackoverflow, but I can't unterstand what problem is.
I see list of book's titles ({item.volumeInfo.title}), but console has error.
Here is my code:
import React, { Component } from 'react';
import { connect } from 'react-redux';
class BookList extends Component {
renderBook(mainData) {
return(
<ul>
{mainData.items.map((item, i) => {
return <li key={i} item={item}>{item.volumeInfo.title}</li>
})}
</ul>
)
}
render(){
return (
<div className="book-row">
<div className="book-info">
{this.props.book.map(this.renderBook)}
</div>
</div>
);
}
}
function mapStateToProps({book}) {
return {book};
}
export default connect(mapStateToProps)(BookList);
It is part of API response:
{ "kind": "books#volumes",
"totalItems": 288,
"items": [
{
"kind": "books#volume",
"id": "yXlOAQAAQBAJ",
"etag": "CG7f2mQ+7Nk",
"selfLink": "https://www.googleapis.com/books/v1/volumes/yXlOAQAAQBAJ",
"volumeInfo": {
"title": "Nineteenth Century Home Architecture of Iowa City",
"subtitle": "A Silver Anniversary Edition"
I tried to do the next keys:
key={item.etag}, key={i}, key={item.volumeInfo.title}
but error is still here.
Please help.
Thank you so much.
Since you are mapping over book:
{this.props.book.map(this.renderBook)}
the ul also needs a key prop:
renderBook(mainData, bookIdx) {
return(
<ul key={bookIdx}>
{mainData.items.map((item, i) => {
return <li key={i} item={item}>{item.volumeInfo.title}</li>
})}
</ul>
)
}
This is because there will be many ul siblings and React needs to tell the difference (same as with li).
However, it is better (if possible) to use a key that is not the index of the array. So, if book and item have a unique identifier, it would be best to use that.
So, it looks like you have another array outside of the sample data you provided:
[
{ "kind": "books#volumes",
"totalItems": 288,
"items": [
{
Reason is you are using two map, and assigning the key in only one, assign the key to <ul> also, because of that it is giving you the error, Try this:
renderBook(mainData, index) {
return(
<ul key={index}>
{mainData.items.map((item, i) => {
return <li key={i} item={item}>{item.volumeInfo.title}</li>
})}
</ul>
)
}

Categories

Resources