Stella
Stella

Reputation: 1868

ReactJS app is unable to fetch data using REST API call

I am trying to develop sample Reactjs web app, where trying to use REST API and fetch some json data. Please see the code.

I am checking in chrome browser after executing the code locally in visual studio, but there is nothing printed in chrome console log. I think, the following code doesn't fetch the data. I didn't find anything wrong in this code. Could someone please help guiding me?

I have used axios and URL : https://jsonplaceholder.typicode.com/users to fetch the data

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import registerServiceWorker from './registerServiceWorker'

import axios from 'axios'

ReactDOM.render(<App />, document.getElementById('root'))
registerServiceWorker()

var element = React.createElement(
  'h1',
  { className: 'greeting' },
  'Test Welcome Message.!'
)
ReactDOM.render(element, document.getElementById('root'))
registerServiceWorker()

export default class ItemLister extends React.Component {
  state = {
    persons: []
  }

  componentDidMount() {
    axios.get('https://jsonplaceholder.typicode.com/users').then(response => {
      // Handle service success response
      console.log(response.data)

      const persons = response.data;
      this.setState({ persons });
    })
  }

  render() {
    return <ul>{this.state. persons.map(person => <li>{person.name}</li>)}</ul>
  }
}

Upvotes: 2

Views: 2071

Answers (2)

Sasha
Sasha

Reputation: 6466

The big problem (if nothing is printing) is probably that your component is not rendering. You are defining, but not rendering ItemLister. It needs to be rendered somewhere. To fix this easily, move the definition of ItemLister above ReactDOM.render, and render <ItemLister /> instead of element. I think that should render the element.

If the component is not rendered, the code within it (including the axios fetch) will not run.

So here's what your code should look like:

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import registerServiceWorker from './registerServiceWorker'

import axios from 'axios'

export default class ItemLister extends React.Component {
  state = {
    persons: []
  }

  componentDidMount() {
    axios.get('https://jsonplaceholder.typicode.com/users').then(response => {
      // Handle service success response
      console.log(response.data)

      const persons = response.data;
      this.setState({ persons });
    })
  }

  render() {
    return <ul>{this.state. persons.map(person => <li>{person.name}</li>)}</ul>
  }
}

ReactDOM.render(<ItemLister />, document.getElementById('root'))
registerServiceWorker()

If that starts the component logging, I think you may run into another issue:

The issue appears to be not with your React code (ie, any component-level issues), but rather with the response from the API not matching your expectations. I ran the following test requests in the Chrome console (with fetch, which works similarly to axios):

fetch('https://jsonplaceholder.typicode.com/users').then(resp => console.log(resp))

That returned a response object that looks like this:

Response {type: "cors", url: "https://jsonplaceholder.typicode.com/users", redirected: false, status: 200, ok: true, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: ""
type: "cors"
url: "https://jsonplaceholder.typicode.com/users"

First thing to notice is that there is no data attribute on this response. Second thing to notice is that body isn't a basic data type. So let's see what body is:

fetch('https://jsonplaceholder.typicode.com/users').then(resp => console.log(resp.body))

The logged response:

ReadableStream {}

Looks like body is a ReadableStream {}.

That probably means we need to "unpack" the response into JSON, so that resp.body is a JSON object, not a ReadableStream.

fetch('https://jsonplaceholder.typicode.com/users').then(resp => resp.json()).then(data => console.log(data))

Bingo. Here's the response:

(10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

An array of ten objects, which appear to be the users you want.

Upvotes: 1

Hemadri Dasari
Hemadri Dasari

Reputation: 33974

Try this. You are doing .map on products but not on persons

   componentDidMount() {
           axios.get('https://jsonplaceholder.typicode.com/users')
     .then( ({data}) => {
          this.setState({ persons: data });
      })
   }

OR

  componentDidMount() {
          axios.get('https://jsonplaceholder.typicode.com/users')
      .then( response => {
           this.setState({ persons: response.data });
       })
   }

Or try with fetch

   componentDidMount(){
 fetch('https://jsonplaceholder.typicode.com/users').then(resp => resp.json()).then(data => this.setState({ persons: data}))
     }

Also don’t forget to add key to li element. You need to add key to the parent element when you do loop like below

  <ul>
      { this.state.persons.map(person => <li key={person.id}> {person.name}</li>)}
 </ul>

If you don’t have unique id from data then add index as key like below

   <ul>
       { this.state.persons.map((person,index) => <li key={“Key”+index}>{person.name}</li>)}
   </ul>

Upvotes: 3

Related Questions