I have a requirement to determine a generic standard approach to read the JSON data ( should be able to read any JSON structure) and display in reactjs page.
I know that if we know JSON structure, we can traverse through it and display the data in the page accordingly. But here JSON structure
should be dynamically determined via code and we should not code specifically for each JSON structure.
For example, I have given Sample1.json and Sample2.json files below. My program should be able to parse Sample1.json if I use it and display
them on the page. If I use Sample2.json, still it should be able to parse them and display the data dynamically. We should not have
code specifically like archive_header.tracking_id or stock_ledger_sales_key.version_number...etc.
Can someone please let me know how to handle this scenario?
Sample1.json
{
"archive_header": {
"tracking_id": "914553536-FRM01-20163609140455-000000001",
"archived_timestamp": "2018-05-08T09:14:04.055-05:00"
},
"journal_record_key": {
"location_number": "389234",
"dept_number": "28822"
},
"journal_record_detail": {
"financial_from_item_number": "771",
"financial_to_item_number": "771"
}
}
Sample2.json
{
"stock_ledger_sales_key": {
"version_number": "12",
"account_month_number": "01",
"account_year_number": "2016"
},
"stock_ledger_sales_detail": {
"mature_increase_mtd_percentage": "1.2",
"mature_increase_stdt_percentage": "2.3",
"mature_increase_ytd_percentage": "2"
}
}
You can just iterate over the keys recursively:
function recursively_iterate(object, parent_name="") {
output = ""
for (key in Object.keys(object)) {
if (typeof object[key] == "object") {
output = output + recursively_iterate(object[key], key)
}
output = output + parent_name + "." + key + ": " + object[key] + "\n"
}
return output
}
To display the information as you said, we can do something like this:
const jsonDOM = json => {
return Object.keys(json).map(key => {
return Object.keys(json[key]).map(child => {
return (<div>
<p>{child}</p>
<p>{json[key][child]}</p>
</div>
);
});
});
};
return (<div>
<h2>JSON 1</h2>
{jsonDOM(json1)}
<h2>JSON 2</h2>
{jsonDOM(json2)}
</div>
);
Here is the live demo
Hope it helps :)
You can use JSON.stringify and <pre> tag to output any json you like.
const sample1 = {
archive_header: {
tracking_id: "914553536-FRM01-20163609140455-000000001",
archived_timestamp: "2018-05-08T09:14:04.055-05:00"
},
journal_record_key: {
location_number: "389234",
dept_number: "28822"
},
journal_record_detail: {
financial_from_item_number: "771",
financial_to_item_number: "771"
}
};
const sample2 = {
stock_ledger_sales_key: {
version_number: "12",
account_month_number: "01",
account_year_number: "2016"
},
stock_ledger_sales_detail: {
mature_increase_mtd_percentage: "1.2",
mature_increase_stdt_percentage: "2.3",
mature_increase_ytd_percentage: "2"
}
};
class App extends React.Component {
render() {
return (
<div>
<h3>sample1</h3>
<pre>
<code>{JSON.stringify(sample1, null, 2)}</code>
</pre>
<h3>sample2</h3>
<pre>
<code>{JSON.stringify(sample2, null, 2)}</code>
</pre>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Related
I have an array of object and want display in a single line in ReactJS. The object look like:
[
{
name:"jane",
age : "20"
},
{
name:"mary",
age : "21"
}
{
name:"john",
age : "19"
}
]
I want display the result to be :
jane 20, mary 21, john 19
e.g
<span className="name>data.name</span> <span className="age>data.age</span>
I have a function but that concat the value but not sure now to get my desire output
const getData = () => {
var val = ''
roles.map((data, inx) => {
val = val + data.name + data.age
})
return (
<span>{val}</span>
)
}
how can I do this
Concatenating like
val = val + data.name + data.age
won't work, because you want JSX elements (spans), not plain strings.
When mapping, check the index. If the index is 1 or more, add a comma before the first span when creating the JSX.
const arr = [
{
name:"jane",
age : "20"
},
{
name:"mary",
age : "21"
},
{
name:"john",
age : "19"
}
]
const App = () => {
return arr.map(({ name, age }, i) => (
<React.Fragment>
{i === 0 ? null : ','}
<span className="name">{name}</span> <span className="age">{age}</span>
</React.Fragment>
));
};
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div class='react'></div>
I have a API for which I would like to loop over to get all the value of its keys. But unfortunately Iam only getting the keys for it.
My code until now:
...
const image_link = JSON.stringify(image);
const parsed_link = JSON.parse(image_link);
console.log('1st link', parsed_link[0].Header) // gives "abc.jpg"
...
...
<div>
{
Object.keys(parsed_link).map((e, i) => {
console.log(parsed_link);
console.log(e); // gives integers like 0,1,2 etc...
console.log(i); // gives integers like 0,1,2 etc...
<img src={e} alt="something" width="300" height="200" />;
return null;
})
}
</div>
...
...
API looks like this:
"Header": [
{
"image": "abc.jpg"
},
{
"image": "xyz.jpg"
},
{
"image": "lmn.jpg"
}
]
Please suggest, where am I goin wrong.
Thanks in advance
If you want to loop through an array, you can use map function.
If you want to loop through an object, you can have to convert the object into an array using Object.keys(YOUR_OBJECT) (if you want to get the key) or Object.values(YOUR_OBJECT) (if you want to get the values) than use map function.
You can directly print the array of data into an array of views. You have to return a view like these:
YOUR_ARRAY.map((item, index) => (
<div>YOUR VIEW</div>
))
// or
YOUR_ARRAY.map((item, index) => {
return(
<div>YOUR VIEW</div>
)
})
Note: you can only return a single parent view inside the return value. If you want to return multiple views inside the return value, you have to wrap them inside a single <div></div> or <React.Fragment></React.Fragment> or <></> parent.
In your code, I saw you wrote parsed_link[0].Header. So I assume that the API returns something like this:
[
{
"Header": [
{
"image": "abc.jpg"
},
{
"image": "xyz.jpg"
},
{
"image": "lmn.jpg"
}
],
...
},
...
]
Here is my answer:
<div>
{
parsed_link[0]['Header'].map((item, index) => (
<img
key={index}
src={item}
alt='something'
width='300'
height='200'
/>
)
}
</div>
I'm VERY new to React and not sure how to render this nested array from an external JSON file. remittance is the only array here one that has nested values that I need to access and render. It logs to the console fine, but won't separate on setState. I apologize if this looks terrible.
class App extends Component {
constructor(props){
super(props);
this.state = {
data,
rName: "",
rDescription: "",
}
}
componentDidMount(){
console.log("Mounted!");
this.display();
};
display = () => {
for (var i = 0; i < data.length; i++){
var remittanceList = data[i].Remittance;
// console.log(remittanceList);
for (var x = 0; x < remittanceList.length; x++){
var rName = remittanceList[x].PayorName;
var rDescription = remittanceList[x].Description;
console.log(rName + rDescription);
this.setState({rName, rDescription});
}
}
}
render() {
var { rName, rDescription } = this.state;
return (
<div className="App">
<Title/>
{this.state.data.map((each, index) => (
<PayInfo key={index}
name={each.Payee.Name}
fax={each.Payee.Fax}
pan={each.Payment.PAN}
cvv={each.Payment.CVV}
exp={each.Payment.Exp}
payorName={rName}
description={rDescription}
/>
))}
</div>
);
}
}
export default App;
And the JSON file is something like this. Because the amount of remittances can very, I can't hardcode in an index to look for every time.
[
{
"Payee": {
"Name": "Bob",
"Fax": "5555555555",
},
"Payment": {
"PAN": 123456,
"CVV": 123,
"Exp": "1/2018"
},
"Remittance": [
{
"PayorName": "Me",
"Description": "Hello World.",
},
{
"PayorName": "You",
"Description": "Hey world.",
},
{
"PayorName": "Snoop",
"Description": "Bye world.",
}
]
},
And this is the PayInfo.js file I should've posted initially! Not sure if this changes any of the answer I got before?
import React from "react";
import "./PayInfo.css";
const PayInfo = props => (
<div>
<div id="payee">
<p>Payee</p>
<p>{props.name}</p>
<p>Fax: {props.fax}</p>
</div>
<hr></hr>
<div id="payment">
<p>Payment</p>
<p>PAN: {props.pan}</p>
<p>CVV: {props.cvv}</p>
<p>Exp: {props.exp}</p>
</div>
<hr></hr>
<div id="remittance">
<p><strong>Remittance(s)</strong></p>
<p>Payor: {props.payorName}</p>
<p>Description: {props.description} </p>
</div>
<hr></hr>
<hr></hr>
</div>
);
export default PayInfo;
In your display method, you are setting the state inside for loop. so only the last value being set to the state.
Please try the below code.
display = () => {
let totalRemittanceArray = []
for (var i = 0; i < data.length; i++) {
var remittanceList = data[i].Remittance;
for (var x = 0; x < remittanceList.length; x++) {
var rName = remittanceList[x].PayorName;
var rDescription = remittanceList[x].Description;
console.log(rName + rDescription);
totalRemittanceArray.push({ rName, rDescription })
}
}
this.setState({totalRemittanceArray})
}
What you might want to do is something like this:
https://codesandbox.io/s/p36jlrz7jj
As you can see I extracted another component PayerInfo. Also React works perfect with map within the render method. I hope my example helps!
Currently you call setState in the for loop and thus overwrite the state every time, but I guess you figured that one out already. I use Array.map to loop over elements within JSX a lot. Dunno if one could do this more nicely, but there is always a possibility to improve ^^
A small improvement here: You could loop in a separate function first and then return the complete Array: https://reactjs.org/blog/2017/09/26/react-v16.0.html
I am facing a issue on extracting the Json data coming from an API.
Please help me to rectify my mistake.
JSON
[
{
"flagshipId":"18",
"BanquetValues":"<p>xzxzxczx<\/p>\n",
"FloorPlan":"[{\"id\":1,\"fileName\":\"megarugas-15243406450731525866511-1.jpg\",\"ifActive\":\"1\"},{\"id\":2,\"fileName\":\"megarugas-15243406467351525866513-2.jpg\",\"ifActive\":\"1\"},{\"id\":3,\"fileName\":\"megarugas-15244876214221526013635-3.jpg\",\"ifActive\":\"1\"}]",
"ChildDescription":"[{\"id\":1,\"childName\":\"Ceremony 1 # Megarugas\",\"description\":\"xczxcxvx\"}]",
"RestaurantId":"695"
}
]
I want to display filename from array of FloorPlan into my carousel.
JSX
render()
{
var banquetImg = this.props.IMG_BASE + this.props.RESTAURANT_BANNER_PATH
return (
<div className="photosSection">
{
this.props.banquetImageList.length != 0
?
<div className="body">
<div className="row">
<Carousel showArrows={true} >
{this.props.banquetImageList.map((row, i) =>
<div key={row.RestaurantAttachmentId} className={"row"}>
<img src={banquetImg + row.FileName} key={row.RestaurantAttachmentId}/>
<p className="get-final-price">Get Final Price</p>
</div>
)}
</Carousel>
</div>
</div>
:
""
}
</div>
);
}
I've tried an approach like #AI.G. and this is my code:
let json_data = [
{
"flagshipId":"18",
"BanquetValues":"<p>xzxzxczx<\/p>\n",
"FloorPlan":"[{\"id\":1,\"fileName\":\"megarugas-15243406450731525866511-1.jpg\",\"ifActive\":\"1\"},{\"id\":2,\"fileName\":\"megarugas-15243406467351525866513-2.jpg\",\"ifActive\":\"1\"},{\"id\":3,\"fileName\":\"megarugas-15244876214221526013635-3.jpg\",\"ifActive\":\"1\"}]",
"ChildDescription":"[{\"id\":1,\"childName\":\"Ceremony 1 # Megarugas\",\"description\":\"xczxcxvx\"}]",
"RestaurantId":"695"
}
];
floor_plan = JSON.parse(json_data[0]['FloorPlan']);
console.log(floor_plan);
And this is what I got from terminal (MacOS 10.13.4, NodeJS v8.11.1):
$ node test.js
[ { id: 1,
fileName: 'megarugas-15243406450731525866511-1.jpg',
ifActive: '1' },
{ id: 2,
fileName: 'megarugas-15243406467351525866513-2.jpg',
ifActive: '1' },
{ id: 3,
fileName: 'megarugas-15244876214221526013635-3.jpg',
ifActive: '1' } ]
You can get each element from floor_plan (which is currently an array).
Is this your target?
I'm trying to convert my data json from an array to an object to be able to consume the data but something went wrong...
Here is the data json sample:
[
{
"id": 1,
"title": "my title",
"imgHero": "../../path/hero.jpg"
}
]
And here is the Vue component:
<template>
<div class="hero">
<img :src="blog.imgHero" alt="hero image" class="heroImg">
<h3 class="heroTitle">{{ blog.title }}</h3>
</div>
</template>
<script>
import tripsJson from '#/data/trips.json'
export default {
name: 'App',
data () {
return {
array: tripsJson,
blog: {}
}
},
created () {
var obj = this.array.reduce(function (acc, cur, i) {
acc[i] = cur
return acc
}, {})
this.blog = obj
console.log(this.blog)
}
}
</script>
Any help or suggestion is more than welcome. Thx