React fetch data and manipulate the response

In this article, we will use react and fetch API to show how to display multi data with one REST API call. To save time we will use React without installing it using npm or yarn.

Starting template will look like this:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Fetch data</title></head>
<body>
<div id="react-container"></div>
<!-- Loading React -->
<script src="https://unpkg.com/prop-types/prop-types.js"></script><script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<!-- Our code  -->
<script type="text/babel">
const { Component } = React
const { render } = ReactDOM

class App extends Component {
constructor(props) {
super(props)
this.state = {
data: []
}
}
render() {
const {data} = this.state
return (
<div>
<h1>Start point</h1>
</div>
)}
}
render(
<App />,
document.getElementById('react-container')
)
</script>
</body>
</html>

For dummy data we will use https://restcountries.eu/ it’s a great API to learn and try a new idea in React.

First, let’s prepare our constructor and state to receive data:

...
constructor(props) {
  super(props)
  this.state = {
   countryNames: [],
   loading:false,
  }
}
...

This creates an empty array for data and variable which hold the state of loading.

Next, let’s use React componentWillMount() to fetch data:

...
componentWillMount(){
this.setState({ loading:true })
fetch('https://restcountries.eu/rest/v1/all')
.then(response => response.json())
.then(json => json.map(country => country.name))
.then(countryNames => this.setState({ countryNames, loading: false }))
}
...

In this point, we have assign data from API to our state countryNames.

Next step is to render out data in browser:

...
render(){
const { countryNames, loading } = this.state
return(
<div>
{(loading) ? 
  <p>Loading Country Names...</p> :
  (!countryNames.length) ?
  <p>No country Names</p> :
  <ul>
    {countryNames.map((x,i) => <li key={i}>{x}</li>)}
  </ul>}
</div>
)
}
...

This will display our data in the template.

Ready example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Fetch data</title></head>
<body>
<div id="react-container"></div>
<!-- Loading React -->
<script src="https://unpkg.com/prop-types/prop-types.js"></script><script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<!-- Our code  -->
<script type="text/babel">
const { Component } = React
const { render } = ReactDOM
class App extends Component {
constructor(props) {
super(props)
this.state = {
countryNames: [],
loading: false,
}
}
componentWillMount(){
this.setState({ loading: true })
fetch('https://restcountries.eu/rest/v1/all')
.then(response => response.json())
.then(json => json.map(country => country.name))
.then(countryNames => this.setState({ countryNames, loading: false }))
}
render() {
const { countryNames, loading } = this.state
return (
<div>
{(loading) ?
<p>Loading Country Names...</p> :
(!countryNames.length) ?
<p>No country Names</p> :
<ul>
{countryNames.map((x,i) => <li key={i}>{x}</li>)}
</ul>}
</div>
)}}
render(<App />,document.getElementById('react-container'))
</script>
</body>
</html>

In this scenario, everything goes good and we have response 200 from API and can display data but what if something failed or API doesn't work for the same reason . To protect our code we can apply another promise which will check if everything is ok and will look like this:

...
status(response){
if(response.status >= 200 && response.status < 300){
return Promise.resolve(response)
}else{
return Promise.reject(new Error(response.statusText))
}
}
...

This will change our code because to use this function in a proper way we should bind it to the constructor and create a variable to store error and change template to display the error message.

The code will look like this:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Fetch data</title></head>
<body>
<div id="react-container"></div>
<!-- Loading React -->
<script src="https://unpkg.com/prop-types/prop-types.js"></script><script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<!-- Our code  -->
<script type="text/babel">
const { Component } = React
const { render } = ReactDOM
class App extends Component {
constructor(props) {
super(props)
this.state = {
countryNames: [],
error:null,
loading: false,
}
this.status = this.status.bind(this)
}
status(response){
  if(response.status >= 200 && response.status < 300){
   return Promise.resolve(response)
  }else{
   return Promise.reject(new Error(response.statusText))
  }
}
componentWillMount(){
this.setState({ loading: true })
fetch('https://restcountries.eu/rest/v1/all')
.then(status)
.then(response => response.json())
.then(json => json.map(country => country.name))
.then(countryNames => this.setState({ countryNames, loading: false }))
.catch(error => this.setState({ error }))
}
render() {
const { countryNames, loading, error } = this.state
return (
<div>
{(error) ?
<p>Problem with API try againg later.</p> :
(loading) ?
<p>Loading Country Names...</p> :
(!countryNames.length) ?
<p>No country Names</p> :
<ul>
{countryNames.map((x,i) => <li key={i}>{x}</li>)}
</ul>}
</div>
)}}
render(<App />,document.getElementById('react-container'))
</script>
</body>
</html>

Last thing for debuging process how to apply console.log with response in Promise chain:

...
.then(response => response.json())
.then((response) => {
console.log(response,'response');
this.setState({ nations:response });
return response
})
.then(json => json.map(country => country.name))
...

In this example, we use the arrow function to put the response in the object where we can play with it but we must remember to use return state with the response to pass it in the next chain. This code shows a situation where we put all data to nations variable which should be defined in constructor state but this is an example.

To view or add a comment, sign in

More articles by Paweł Grajewski

  • React Native todo app

    Useful links: https://facebook.github.

  • Splice array prototype

    When we want to add or remove elements from the array best way to do this is to apply splice or shift method. First…

  • Using spread operator to store Form values in React

    Storing data from the form is a common task in React. Very useful for this task is javaScript spread operators and…

  • Using Context and HashRouter in React

    We will create React app which will use context and HashRouter. The will fetch data from API and supply all app with…

  • Arrow function playground

    What can be more useful than a shortcut in programming languages? An arrow function is one of these things which can be…

  • Online sandbox code editor for fast prototyping

    Creating a project takes time. We must adjust the virtual environment or add npm packages to the project.

  • React static page with React-app and Reactstrap

    In this tutorial, we will learn how to use React react-app and dedicated version of bootstrap for react Reactstrap. At…

    1 Comment
  • Django and Selenium

    Selenium is a project which aim is to test site with webdriver. All most popular browser has to develop webdriver which…

  • Deploy Django project on Heroku

    This story will be about how to build basic project in Django and deploy it in Heroku. It can be good practice for…

Explore content categories