How to display json files content one after another when clicked.
I have 3 json files**(biology.json,chemistry.json and physics.json)** that I want to show its content one after another on showmore button click.
biology.json
[
{ "id" : 1, "course" : "Bio101"},
{ "id" : 2, "course" : "Bio102" }
]
chemistry.json
[
{ "id" : 3, "course" : "Chem101"},
{ "id" : 4, "course" : "Chem102" }
]
physics.json
[
{ "id" : 5, "course" : "Physics101"}
]
I also have file_count.json that stores all the 3 json files above including all total amount of data in each file.
file_count.json
[
{ "id" : 1, "filename" : "biology.json", "content_total" : 2},
{ "id" : 2, "filename" : "chemistry.json", "content_total" : 2 },
{ "id" : 3, "filename" : "physics.json", "content_total" : 1 }
]
what am trying to achieve: I want to load content of each of the 3 files (biology.json,chemistry.json and physics.json) one after another when button is clicked. based on their filesname or any other means in file_count.json. For instance, on page loading fetched biology.json data, on next showmore button click fetch Chemistry.json data, next fetch physics.json data and so on.
With code below, I can successfully fetch biology.json data. how do I fetch chemistry.json and physics.json data
one after another when showmore button is clicked. Thanks
Here is the coding so far
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="build/react.min.js"></script>
<script src="build/react-dom.min.js"></script>
<script src="build/browser.min.js"></script>
<script src="build/jquery.min.js"></script>
<div id="app"></div>
<script type="text/babel">
class Application extends React.Component {
constructor(props) {
super(props)
this.state = {
file_count : [],
limit : 1,
data:[]
};
this.showMore = this.showMore.bind(this);
}
componentDidMount() {
//load filecount.json
$.ajax({
type: "POST",
url: "http://localhost/axios/axios-master/dist/file_count.json",
cache: false,
crossdomain:true,
success: function(file_count) {
this.setState({file_count: file_count});
}.bind(this),
error: function(jqXHR) {
console.log(jqXHR);
}.bind(this)
});
//load biology.json
$.ajax({
type: "POST",
url: "http://localhost/axios/axios-master/dist/biology.json",
cache: false,
crossdomain:true,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(jqXHR) {
console.log(jqXHR);
}.bind(this)
});
}
showMore() {
// load chemistry.json file on click
// load physics.json file on click
}
get finished() {
if (this.state.limit == 0) {
// you can also set state for loading image
return <li key={"done"}>No More json files to Load. Content
finished</li>;
}
return null;
}
render() {
return <div className="container">
{this.finished}
<div className="row">
<h3>List of records</h3>
<ul>
{this.state.data.map((f, i) =>
<li key={i}>{f.id} - {f.course}</li>)}
</ul>
</div>
<p>
<a className="btn btn-primary" onClick={this.showMore}>Show
more</a>.
</p>
</div>;
}
}
ReactDOM.render(<Application />, document.getElementById('app'));
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
</body>
</html>
Updated part of the code based on solution provided by @Rahul and @t3__rry
@t3__rry thanks for your response. I have Updated the code below to reflect your solutions but it throws error unexpected token. expected ";" at this line of code pointing to the currentIndex colon
currentIndex: prevState.currentIndex + 1,
here is the code
import React, { Component } from 'react';
//import axios from 'axios';
export default class Paginate extends Component {
constructor(props) {
super(props)
this.state = {
file_count : [],
data:[],
currentIndex: 0,
};
this.showMore = this.showMore.bind(this);
}
async fetchData(filename) {
const response = await fetch(`http://localhost/${filename}`);
const data = await response.json()
return data;
}
async componentDidMount() {
const fileCountJSON = await this.fetchData('http://localhost/filecount.json');
if (fileCountJSON) {
// will return an array with your file names e.g. ['biology.json', 'chemistry.json'] ...
const filenames = fileCountJSON.map(file => file.filename);
this.setState(() => ({
fileCount: filenames,
}));
// then fetch the firstData in the list of fileCount
const { currentIndex, fileCount } = this.state;
const initialData = await this.fetchData(fileCount[currentIndex]);
// and set the state based on what you get
this.setState((prevState) => {
data: initialData,
// and increment currentIndex to be able to trigger the next load
currentIndex: prevState.currentIndex + 1,
});
}
}
// in show more do what you did previously
showMore() {
const { currentIndex, fileCount } = this.state;
// duplicated code here, we could abstract it into a function
if (currentIndex < fileCount.length - 1) { // checks if we still have fileCount items
const data = await this.fetchData(fileCount[currentIndex]);
this.setState((prevState) => ({
data,
currentIndex: prevState.currentIndex + 1,
}));
return;
}
}
render() {
currentIndex < fileCount.length - 1 ? (
this.state.data.map((f, i) => <li key={f.id}>{f.id} - {f.course}</li>)
) : (
<li>No More json files to Load. Content finished</li>
)
}
}
@Rahul thanks for responding. I have updated the code to reflect your solution. When I run it, no error nothing showed.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="build/react.min.js"></script>
<script src="build/react-dom.min.js"></script>
<script src="build/browser.min.js"></script>
<script src="build/jquery.min.js"></script>
<div id="app"></div>
<script type="text/babel">
class Application extends React.Component {
constructor(props) {
super(props)
this.state = {
file_count : [],
limit : 1,
data:[],
index:0
};
this.showMore = this.showMore.bind(this);
}
componentDidMount() {
//load filecount.json
$.ajax({
type: "POST",
url: "http://localhost/axios/axios-master/dist/file_count.json",
cache: false,
crossdomain:true,
success: function(file_count) {
this.setState({file_count: file_count});
}.bind(this),
error: function(jqXHR) {
console.log(jqXHR);
}.bind(this)
});
const { file_count, index } = this.state;
if(index>file_count.length-1){
console.log("No more file to load")
return;
}
const { filename } = file_Count[index];
//Use file name to make api call
$.ajax({
type: "POST",
url: "http://localhost/axios/axios-master/dist/filename",
cache: false,
crossdomain:true,
success: function(data) {
//this.setState({data: data});
this.setState({data:data, index: this.state.index+1});
}.bind(this),
error: function(jqXHR) {
console.log(jqXHR);
}.bind(this)
});
}
showMore() {
const { file_count, index } = this.state;
if(index>file_count.length-1){
console.log("No more file to load")
return;
}
const { filename } = file_Count[index];
//Use file name to make api call
$.ajax({
type: "POST",
url: "http://localhost/axios/axios-master/dist/filename",
cache: false,
crossdomain:true,
success: function(data) {
//this.setState({data: data});
this.setState({data:data, index: this.state.index+1});
}.bind(this),
error: function(jqXHR) {
console.log(jqXHR);
}.bind(this)
});
}
render() {
return <div className="container">
<div className="row">
<h3>List of records</h3>
<ul>
{this.state.data.map((f, i) =>
<li key={i}>{f.id} - {f.course}</li>)}
</ul>
</div>
<p>
<a className="btn btn-primary" onClick={this.showMore}>Show
more</a>.
</p>
</div>;
}
}
ReactDOM.render(<Application />, document.getElementById('app'));
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
</body>
</html>