Issue in accessing API/json with multiple sections - json

I'm trying to display all sections of the following json file into my reactjs page: https://api.myjson.com/bins/cdres
below is the code:
import React, { Component } from 'react';
import {render} from "react-dom";
class apps extends Component {
state = {
data: {
segments: [],
totals: [],
}
}
componentWillMount(){
fetch('https://api.myjson.com/file', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json',
'Authorization': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiR3JlZyIsInVuaXF1ZV9uYW1lIjoiZ2dyYWZmIiwibmJmIjoxNTI0ODM5Nzc1LCJleHAiOjE1MjQ5MjYxNzV9.xhvdfaWkLVZ_HLwYQuPet_2vlxNF7AoYgX-XRufiOj0'
},
}
) /*end fetch */
.then(results => results.json())
.then(data => this.setState({ data: data }))
}
render() {
console.log(this.state.data);
return (
<div className="clientContainer">
{
this.state.data.segments.map( item =>(
<div>
<span> {item.clientName} </span>
</div>
))
}
{
this.state.data.totals.map(item =>(
<div>
<span> {item.segmentType} </span>
<span> {item.adjTotalSqrFt} </span>
</div>
))
}
</div>
);
}
}
export default app;
...the code works for consuming data from the segments and totals section of the json file, but am having trouble getting the id and username from the top section?

data is an object rather than an array so calling map on it triggers an error.
Simply do this.state.data.segments.map(...) instead, and change your initial state to
state = { data: { segments: [] } }

map is a function of array. The data is an object while data.segments is an array. You will need to change the code as below
<div className="clientContainer">
{
this.state.data.segments.map( item =>( //change here
<div>
<span> {item.clientName} </span>
</div>
))
}
</div>

Related

How to use Filter with ReactJS to prevent duplicates in an array from being displayed

I have a ReactJS page with three dropdown list, two of the dropdown list are displaying duplicate values. The values are being consumed from a json file. I researched using filter to remove the duplicates, but I'm unsure as to how I'm to apply it to my array when using React JS along with Fetch.
I created a function which employs the filter method, but I'm uncertain as to how I'm to implement it onto data: [], which contains the data consumed from the json file. This is the sample json file: https://api.myjson.com/bins/b1i6q
This is my code:
import React, { Component } from "react";
class Ast extends Component {
constructor() {
super();
this.state = {
data: [],
cfmRateFactor: "10"
};
} //end constructor
change = e => {
this.setState({
[e.target.name]: e.target.value
});
}; //end change
removeDups(array) {
return array.reduce((result, elem) => {
if (!result.some((e) => e.clientName === elem.clientName)) {
result.push(elem);
}
return result;
} , []);
}
componentWillMount() {
fetch("https://api.myjson.com/bins/b1i6q", {
method: "GET",
headers: {
Accept: "application/json",
"Content-type": "application/json"
}
/*body: JSON.stringify({
username: '{userName}',
password: '{password}'
})*/
}) /*end fetch */
.then(results => results.json())
.then(data => this.setState({ data: data }));
} //end life cycle
render() {
console.log(this.state.data);
return (
<div>
<div className="container">
<div className="astContainer">
<form>
<div>
<h2>Memeber Selection:</h2>
{["clientName", "siteName", "segmentName"].map(key => (
<div className="dropdown-padding">
<select key={key} className="custom-select">
{this.state.data.map(({ [key]: value }) => (
<option key={value}>{value}</option>
))}
</select>
</div>
))}
</div>
<div className="txt_cfm">
<label for="example-text-input">Modify CFM Rate Factor:</label>
<input
class="form-control"
type="textbox"
id="cfmRateFactor"
name="cfmRateFactor"
value={this.state.cfmRateFactor}
onChange={e => this.change(e)}
/>
</div>
<div>
<div>
<button type="submit" className="btn btn-primary">
Submit
</button>
</div>
</div>
</form>
</div>
</div>
</div>
);
}
}
export default Ast;
Could I please get some help with this? I'm still very new to using React JS.
You could use Map, it's a data structure for keeping key-value pairs. It will give you best performance for large data.
removeDuplicates(arr) {
const map = new Map();
arr.forEach(v => map.set(v.abc_buildingid, v)) // having `abc_buildingid` is always unique
return [...map.values()];
}
// this hook is better to start fetching data than componentWillMount
componentDidMount() {
fetch("https://api.myjson.com/bins/b1i6q", {
method: "GET",
headers: {
Accept: "application/json",
"Content-type": "application/json"
}
})
.then(results => results.json())
.then(data => this.setState({ data: this.removeDuplicates(data) })); // use the defined method
} //end life cycle
filter won't solve your problem. But reduce will.
You could have the following :
function removeDups(array) {
return array.reduce((result, elem) => {
if (!result.some((e) => e.abc_buildingid === element.abc_buildingid)) {
result.push(elem);
}
return result;
} , []);
}

ReactJS error unhandled Rejection - How to access json file with multiple sections?

Am following a tutorial on using Fetch with ReactJS, am able to access a certain section of data from the API/json, but when attempting to access other sections, I get an error. this is the JSON file, which is using the following API: https://api.myjson.com/file1
the code
import React, { Component } from 'react';
import {render} from "react-dom";
import './BuildingSimulation.css';
class BuildingSimulation extends Component {
state = { data: [] }
componentWillMount(){
fetch('https://api.myjson.com/bins/zb5kf', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json',
'Authorization': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiR3JlZyIsInVuaXF1ZV9uYW1lIjoiZ2dyYWZmIiwibmJmIjoxNTI0ODM5Nzc1LCJleHAiOjE1MjQ5MjYxNzV9.xhvdfaWkLVZ_HLwYQuPet_2vlxNF7AoYgX-XRufiOj0'
},
}
) /*end fetch */
.then(results => results.json())
.then(data => this.setState({ data: data }))
}
render() {
console.log(this.state.data);
return (
<div className="clientContainer">
{
this.state.data.map( item =>(
<div>
<span> {item.clientName} </span>
</div>
))
}
</div>
);
}
}
export default BuildingSimulation;
...so I'm able to get information from the Segments section to display in the page, but how do I also get the ID in the header of the json file and data from the totals section to display in my page as well?
You are storing only segment data from the API response. To access the other data you need to store the entire reponse inside the state. So change
.then(data => this.setState({ data: data.segments }))
to
.then(data => this.setState({ data: data }))
Now you can access all the response data.
Update:
After doing this, the this.state.data represent the json data. So to access segments, use this.state.data.segments. To access totals, use this.state.data.totals and so on.
You can also burst the object like this:
state = {
id = '',
segments: [],
totals: []
}
And on the after fetch do like this:
.then(results => results.json())
.then(({
id = '',
segments = [],
totals = []
}) => this.setState({
id,
segments,
totals
}));
Finally, on your render use the state data like this:
render() {
const {
id,
segments,
totals
} = this.state;
return (
<p>ID: {id}</p>
<ul>
{
segments.map((segment) => <EachSegmentComponent segment={segment} />)
}
</ul>
<ul>
{
totals.map((total) => <EachTotalComponent total={total} />)
}
</ul>
)
}
Hope this helps.

Accessing certain item after fetching data from API with react

I am learning react and stumbled on something that seems like an absolute beginner problem. Anyway I am fetching data from an API and would like to know how to get a certain element from the JSON. I have tried different variations with [] but with no success.
JSON:
[{"name":"gfhf","id":1,"organizer":"hfgh"},{"name":"World Cup","id":2,"organizer":"FIFA"}]
React code:
import React, { Component } from "react";
import Tournaments from "./Tournaments";
const tournyAPI = 'http://localhost:8080/api/tournaments';
class template extends Component {
constructor() {
super();
this.state = {
data: [],
}
}
componentDidMount() {
fetch(tournyAPI)
.then((Response) => Response.json())
.then((findresponse) => {
console.log(findresponse)
this.setState({
data:findresponse,
})
})
}
render() {
return (
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="jumbotron text-center">
{
this.state.data.map((dynamicData, key) =>
<div>
<h1>{dynamicData.name}</h1>
</div>
)
}
</div>
</div>
</div>
</div>
);
}
}
export default template;
My goal would be to display only World cup for example.
You can filter out whatever you want from the response from the API. Like below:
Notice the line findresponse.filter(res => res.name === "World Cup");
componentDidMount() {
fetch(tournyAPI)
.then((Response) => Response.json())
.then((findresponse) => {
console.log(findresponse)
findresponse.filter(res => res.name === "World Cup");
this.setState({
data:findresponse,
})
})
}

How to use React SetState on nested data with empty top level names?

I have the following JSON data:
[
{"ID":1,"Latitude":"-41.276253","Longitude":"173.283842","Image":"Church.jpg"},
{"ID":2,"Latitude":"-41.267783","Longitude":"173.279114","Image":"Centre.jpg"}
]
I am trying to import it so it can be rendered & started with the following code:
componentDidMount() {
fetch('/home/briefsJson').then(response => response.json()).then(data => {
console.log(data);
this.setState({
latitude: data.Latitude,
longitude: data.Longitude,
image: data.Image
});
});
}
This doesn't as the data is multidimensional/nested. But every example I've found is using better structured data with top level names.
How can I use setState & render to display this data?
If you want to import json from a js file you would do it like this.
Data.js
const Data = [
{"ID":1,"Latitude":"-41.276253","Longitude":"173.283842","Image":"Church.jpg"},
{"ID":2,"Latitude":"-41.267783","Longitude":"173.279114","Image":"Centre.jpg"}
]
export default Data
Then import it where you want to use it. Now you can map through the data as you like.
App.js
import Data from './data'
import React, {Component} from 'react'
class App extends Component {
state = { Data:[] }
componentDidMount() { this.setState({ Data: Data }) }
render() {
return(
<div> {this.state.Data.map(item => <div> The id is: {item.ID} </div> }</div>
)
}
}
Maybe you want to change the names of the items, and return a new data structure with less attributes this is how you would do it.
componentDidMount() {
fetch('/home/briefsJson').then(response => response.json()).then(data => {
const newData = data.map(item => {
latitude:item.Latitude,
longitude: item.Longitude,
image: item.Image}
}
this.setState({
Data:newData
});
});
}
Now if you want to display this data in render.
renderData = () => {
return (
<div>
{this.state.Data.map(item => (
<div>
{item.latitude}
{item.longitude}
<img src={item.img} />
</div>
)}
</div>
)
}
render() {
return (
<div> {this.renderData()} </div>
)
}
It would probably just be easier to first construct what you want, then do a mapping in the rendering. It looks like you don't even need to do anything to convert it, since the json data is exactly what you want in the first place. So:
componentDidMount() {
fetch('/home/briefsJson').then(response => response.json()).then(data => {
console.log(data);
this.setState({ data });
});
}
render() {
return (
<div>
{this.state.data.map(datum => (element))}
</div>
);
}

React output JSON from API

I have managed to get JSON from my api I have created, however I am having trouble actually rendering that JSON. I have managed to output it in the console by 'stringify'-ing it, however I cannot seem to actually render JSON to the page.
import React, { Component } from 'react';
import './App.css';
import $ from 'jquery';
function getData() {
return $.ajax({
type: "GET",
url: 'http://localhost:3001/data',
data: {},
xhrFields: {
withCredentials: false
},
crossDomain: true,
dataType: 'json',
success: handleData
});
}
function handleData(data /* , textStatus, jqXHR */ ) {
console.log(JSON.stringify(data));
return JSON.stringify(data);
}
class App extends Component {
render() {
return (
<div className="App">
<header>
<h2>Last Application Deployment </h2>
</header>
<div id='renderhere'>
{JSON.stringify(getData().done(handleData))}
</div>
</div>
);
}
}
export default App;
you cant execute a function in render method in return.you can use react lifecycles and store result in state like this =>
class App extends Component {
state = {result : null}
componentDidMount = ()=>{
$.ajax({
type: "GET",
url: 'http://localhost:3001/data',
data: {},
xhrFields: {
withCredentials: false
},
crossDomain: true,
dataType: 'json',
success: (result)=>{
this.setState({result : result});
}
});
};
render() {
return (
<div className="App">
<header>
<h2>Last Application Deployment </h2>
</header>
<div id='renderhere'>
{this.state.result && and what you want because i dont know why you want use JSON.stringfy - you use .map() or ...}
</div>
</div>
);
}
}
I suggest you see this article and this.
I've made a demo of how you can solve this: http://codepen.io/PiotrBerebecki/pen/amLxAw. The AJAX request should not be made in the render method but in a componentDidMount() lifecycle method. Also, it's best to store the response in state. Please see the guidance in the React docs: https://facebook.github.io/react/tips/initial-ajax.html
Fetch data in componentDidMount. When the response arrives, store the data in state, triggering a render to update your UI.
Here is the full code:
class App extends React.Component {
constructor() {
super();
this.state = {
time: '',
string: ''
};
}
componentDidMount() {
$.ajax({
type: "GET",
url: 'http://date.jsontest.com/'
})
.then(response => {
this.setState({
time: response.time,
string: JSON.stringify(response)
});
})
}
render() {
return (
<div className="App">
<header>
<h2>Last Application Deployment </h2>
</header>
<div id='renderhere'>
Time: {this.state.time} <br /><br />
String: {this.state.string}
</div>
</div>
);
}
}
ReactDOM.render(
<App />, document.getElementById('content')
);