How to display value got from API into ReactJS page - reactjs

let resultofapi is declared globally and I initialized it with the value I received from API. I want to display that value to my react js page (inside a table). When I print the value inside the API it returns me output {"similarity_score":0.9999999404}.but when I access it outside the API, it gives me value=undefine
pd.usage()
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
**pd.semantic(
pd
.semantic(textarea1, textarea2)//these are forms data
.then(response => {
console.log(response); //output={"similarity_score":0.670276463}
*resultofapi = response;* //output=resultofapi={"similarity_score":0.670276463}*
})**
.catch(error => {
console.log(error);
})
)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
console.log(resultofapi)//output=undefined

Make a state object and setState it with the API Data. From that you can access it allover your class.
this.state = {
items: []
};
componentDidMount() {
fetch("https://url.url.com")
.then(res => res.json())
.then(
(result) => {
this.setState({
items: result.items
});
},
// 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
});
}
)
return (
<ul>
{items.map(item => (
<li key={item.name}>
{item.name} {item.price}
</li>
))}
</ul>
);

Related

State is being changed, but display not updating

I've seen quite a few posts about this, but none of the solutions seem to work for me.
I have a render method that is being mapped to list the different sections stored in a state(this part works as expected):
render() {
return (
<ThemeProvider theme={theme}>
<Div>
<hr />
<div>
{this.state.sections.map(section => (
<div
className="mb-3"
key={section.section_title}
>
<h3>{section.section_title}</h3>
</div>
))}
</div>
)
}
However, I have a modal that allows you to create a new section by giving it a name and clicking submit. That does create it and add it to my database table as expected. But, then when I run the method to pull that data down, and change the state to include the new section, it works, and does indeed change the state to include the new section. But it does not update the display unless I reload the page. Can anyone see why?
getProjectSections(projId) {
fetch(API_URL + `/billingcalculator/sections/distinct/${projId}`)
.then((res) => {
if (!res.ok) {
throw new Error()
}
return res.json()
})
.then((result) => {
let listedSections = [...result];
this.setState({ sections: listedSections });
})
.catch((error) => {
console.log(error);
})
}
the getProjectSections() runs when you click the submit button a creating a new section which runs this:
handleSectionCreateSave() {
fetch(API_URL + `/billingcalculator/section/create`, {
method: "PUT",
body: JSON.stringify({
projectId: this.props.billProjId,
sectionTitle: this.state.newSectionTitle
}),
headers: { "Content-Type": "application/json" },
})
.then((res) => {
if (!res.ok) {
throw new Error();
}
return res.json();
})
.then((data) => console.log(data))
.catch((err) => console.log(err))
.then(this.getProjectSections(this.props.billProjId))
.then(this.setState({ showSectionModal: false }))
.catch((err) => console.log(err));
}
You are calling state updates before request happens:
handleSectionCreateSave() {
fetch(API_URL + `/billingcalculator/section/create`, {
method: "PUT",
body: JSON.stringify({
projectId: this.props.billProjId,
sectionTitle: this.state.newSectionTitle
}),
headers: { "Content-Type": "application/json" },
})
.then((res) => {
if (!res.ok) {
throw new Error();
}
return res.json();
})
.then((data) => console.log(data))
.catch((err) => console.log(err))
// you called these function now, instead after fetch
// use () =>
.then(() => this.getProjectSections(this.props.billProjId))
.then(() => this.setState({ showSectionModal: false }))
.catch((err) => console.log(err));
}

How can I dynamically rerender my api to my webpage?

So I have this api and I am making a get request in my ComponentDidMount() to dynamically render it to my page and it works. The issue I am facing is when I make a post request to add items to the list, it does not show on my webpage unless I refresh it. The backend is my data.json so I don't know if that is the problem but essentially when I make a post request, I am adding data to my data.json and I want that to rerender on my page without me refreshing it.
componentDidMount() {
axios.get("/api/workboard")
.then(res => {
res.data["boardLists"].map((item, key) => {
// console.log(Object.keys(item)[0])
this.setState(prevState => ({
data: [...prevState.data, item],
titles: [...prevState.titles, Object.keys(item)[0]]
}))
})
// console.log(this.state.titles)
// console.log(this.state.data)
}).catch(err => console.log(err))
}
addListItemHandler = () => {
axios({
method: 'post',
url: 'api/workboard/0/list',
data: {
title: "Untitled" ,
description: "No Description"
}
})
.then(res => {
console.log(res)
})
.catch(err => console.log(err));
}
render() {
let board = this.state.data.map((item, key) => {
return <WorkBoardContainer
key={key}
title={item[this.state.titles[key]]["title"]}
listItems={item[this.state.titles[key]]["list"].map((i) => {
return i["title"]
})}
/>
})
return (
<div className={classes.App}>
<AddButton addListItemHandler={this.addListItemHandler}/>
{board}
</div>
);
}
Try moving the fetching part as a seperate function and call it again once the post request is done.
componentDidMount() {
// fetch data when component is mounted
this.fetchData();
}
fetchData = () => {
axios.get("/api/workboard")
.then(res => {
res.data["boardLists"].map((item, key) => {
this.setState(prevState => ({
data: [...prevState.data, item],
titles: [...prevState.titles, Object.keys(item)[0]]
}))
})
}).catch(err => console.log(err))
}
addListItemHandler = () => {
axios({
method: 'post',
url: 'api/workboard/0/list',
data: {
title: "Untitled" ,
description: "No Description"
}
})
.then(res => {
console.log(res);
// fetch data again once post is done.
this.fetchData();
})
.catch(err => console.log(err));
}

problem with fetch in componentDidMount()

my list of users is undefined when i try to console.log it.
Maybe i didn't get something ?
I'd like to get my list of users from my api who works (tested with postman) and put it into the console next i'd like to map my users to show it on the app
class Test extends Component {
constructor(props) {
super(props);
this.state = {
users: [],
}
}
componentDidMount() {
console.log("component did mount");
fetch("/user/list")
.then(res => {
return res.json();
})
.then(users =>
this.setState({users}, () =>
console.log("list of users => " + users)));
}
render() {
return (
<div className="form">
<ul>
{this.state.users.map((user) =>
<li key="user._id">{ user.name }</li>
)}
</ul>
</div>
);
}
} export default Test;
Thanks for help !
You are calling res.json() rather than returning res.json() from the first then on your fetch call
I've found this pattern to be helpful:
fetch(url)
.then(res => res.ok ? res.json() : Promise.reject())
As your code is now, users (the parameter in the second then would be undefined, because you are not returning anything from the first then
you have to return the res.json() to use it in the next .then()
.then(res => {
res.json();
})
should be
.then(res =>
res.json();
)
Or
.then(res => {
return res.json();
})
https://javascript.info/promise-chaining
You should be passing your res into res.json() and returning the results into your state.
componentDidMount() {
console.log("component did mount");
fetch("/user/list")
.then(res => res.json())
.then(users =>
this.setState(users,
() => {
console.log("list of users => " + users)
})
);
}
Michael Jasper response help me so much!
I found that fetch with GET method does not work if we pass any request body.
the full example is here
https://github.com/alexunjm/todo-list-react
const buildRequestOptions = ({
method = "GET",
raw = null, // I had my error here!, with GET raw need to be null
customHeaders = {name: 'value'},
}) => {
var myHeaders = buildHeaders(customHeaders);
var requestOptions = {
method,
headers: myHeaders,
body: raw,
redirect: "follow",
};
return requestOptions;
};
const listTasks = () => {
const url = `${uriBase}/task/sample`;
const requestOptions = buildRequestOptions({
customHeaders: { "Content-Type": "application/json" },
});
return fetch(url, requestOptions);
}
const asyncFn = ({
promiseToWait,
pendingFn,
successFn,
errorFn,
}) => {
return (dispatch) => {
dispatch(pendingFn());
promiseToWait
.then((res) => {
if (res.ok) {
return res.json();
}
// handled from server status 422 and 401
if (res.status === 422) {
// error message on body from server
return res.json();
}
if (res.status === 401) {
// custom error message hardcoded
return {errors: {action: 'no authorized'}}
}
console.log("http response no controlled", res);
return Promise.reject();
})
.then((body) => {
if (body.errors) {
const errors = Object.keys(body.errors).map(
(key) => key + " " + body.errors[key]
);
dispatch(errorFn(errors.join("; ")));
} else {
dispatch(successFn(body));
}
return body;
})
.catch((error) => {
console.log("error", error);
dispatch(errorFn("Unavailable server connection"));
});
};
};
const queryTasks = () => {
return asyncFn({
promiseToWait: listTasks(),
pendingFn: apiPending,
successFn: apiSuccessList,
errorFn: apiError,
});
}

trying to set the state of react-highcharts, but it isn't working?

As stated in the title, how to set the data with a state value in react for highcharts? The value of this.state.number is 0 / undefined
CODE
getFirstMonthOpenEnhancements(){
fetch(`http://ca-fpscfb2:4000/1stMonthOpenedEnhancements?airline=${this.state.airlineName}&product=${this.state.airlineProduct}`)
.then(response => response.json())
.then( response =>
this.setState(
{
number: parseInt(response.data.total)
}
))
.catch(err => console.error(err))
}
componentDidMount(){
this.getFirstMonthOpenEnhancements();
let chart = this.refs.chart.getChart();
chart.series[4].setData([this.state.number, 4, 4, 4]);
}
The this.state.number property is undefined because your API request is asynchronous, so when you are asking for the value of this.state.number its undefined because your API call hasn't returned yet.
Theres a couple different solutions but in my opinion the most elegant is returning a promise.
getFirstMonthOpenEnhancements(){
return new Promise((resolve, reject) => {
fetch(`http://ca-fpscfb2:4000/1stMonthOpenedEnhancements?airline=${this.state.airlineName}&product=${this.state.airlineProduct}`)
.then(response => response.json())
.then( response =>
return resolve(parseInt(response.data.total))
))
.catch((err) => { return reject(err) });
});
}
componentDidMount(){
this.getFirstMonthOpenEnhancements()
.then((someNumber) => {
let chart = this.refs.chart.getChart();
chart.series[4].setData([someNumber, 4, 4, 4]);
this.setState({ number: someNumber });
})
.catch((err) => { console.log(err); });
}

Why I have errors in React with load data from database Postgresql?

I have database with 2 tables Person and City with relationship One-to-Many
Example of row in Person:
{id: 1, name: 'John', city: 5}
Example of row in City:
{id: 5, name: 'New York'}
In React app, I get values from database Postgresql, save it in state and show in component (table):
...
render() {
return (
<table>
<thead>
<TableHeader/>
</thead>
<tbody>
{this.props.person.map(item => {
const city = this.props.city.find(el => el.id === item.city);
return (<TableRow key={item.id} directory={item} directoryC={city}/>);
})}
</tbody>
</table>
);
In TableRow I add it to table rows:
...
render() {
return (
<tr>
<td>{this.props.directory.name}</td>
<td>{this.props.directoryC.name}</td>
</tr>
);
}
This code is works, but in console I see this error:
Uncaught (in promise) TypeError: Cannot read property 'name' of undefined
What happend? How can I fix this error?
Update. Fetch code:
onHandlePersonFetch() {
fetch(`${'127.0.0.1:3000'}/person`, {
method: 'GET'
})
.then((response) => {
if (response.status >= 400) {
throw new Error('Bad response from server');
}
return response.json();
})
.then(data =>
this.setState({ person: data })
);
}
onHandleCityFetch() {
fetch(`${'127.0.0.1:3000'}/city`, {
method: 'GET'
})
.then((response) => {
if (response.status >= 400) {
throw new Error('Bad response from server');
}
return response.json();
})
.then(data =>
this.setState({ city: data })
);
}
That is not the proper way to do error handling in promises... Change to this:
onHandlePersonFetch() {
fetch(`${'127.0.0.1:3000'}/person`)
.then(response => response.json())
.then(data => this.setState({ person: data }))
.catch(err => console.log(err));
}
onHandleCityFetch() {
fetch(`${'127.0.0.1:3000'}/city`)
.then(response => response.json())
.then(data => this.setState({ city: data }))
.catch(err => console.log(err));
}
Also, if you are doing async data fetching (which you are...) it should be done within the componentDidMount lifecycle method...

Resources