learningMonk
learningMonk

Reputation: 1401

Results are not populating after fetching from API using React

I am working with some examples to fetch the data from an API using fetch. But, it is returning nothing in view. What i am doing wrong? Why it is not populating? Here is a link to the code.

Application code here:

import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import axios from 'axios';
import './style.css';

const url='https://10degrees.uk/wp-json/wp/v2/posts';

class App extends Component {
  constructor() {
    super();
    this.state = {
      name: 'React',
      searchInput: 'tirur',
      avatarDatas: []
    };
    this.fetchData = this.fetchData.bind(this);
  }

  componentDidMount(){
    this.fetchData(url);
  }

  fetchData = (apiToFetch)=>{
     fetch(apiToFetch)
     .then(result=>result.json())
     .then(avatarData=>{
       this.setState({
         avatarDatas : avatarData
       })
     })
     .catch((error) => console.log(error));
  }

  render() {
    console.log(this.state.avatarDatas)
    return (
      <div>
        <Hello name={this.state.name} />
        <p>
        {this.state.avatarDatas.map(item=>{
          <div>{item}</div>
        })}
        </p>
      </div>
    );
  }
}

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

Upvotes: 0

Views: 56

Answers (1)

Alexander van Oostenrijk
Alexander van Oostenrijk

Reputation: 4754

Your code is fetching data from the remote URL correctly. However, you're using the map function in your render method wrong. You have:

{this.state.avatarDatas.map(item=>{
  <div>{item}</div>
})}

This does indeed map through all the entries in avatarDatas, but the function the callback you've provided the map isn't returning anything. You've written a function block with a JSX statement in it, and no return statement. What you should have written is:

{this.state.avatarDatas.map(item=>{
  return (<div>{item}</div>);
})}

or even this, where there isn't an actual function block but just a return value:

{this.state.avatarDatas.map(item=>
  <div>{item}</div>
)}

At this point, the avatarDatas still won't be listed, because the JSX in your map callback is trying to have item rendered. item is an object, and React won't know how to convert it to a string. Rather do this:

{this.state.avatarDatas.map(item=>
  <div>{item.title.rendered}</div>
)}

(Or any other of the many fields that each avatarData has.)

Finally, React may still issue a warning, saying that each item in a list must have a unique key. Whenever you use map to create a number of elements, React expects you to give a unique identifier to each element, which it will use to identify that element when it needs to update your list during rerendering. That means that you should do this:

{this.state.avatarDatas.map((item, index) =>
  <div key={index}>{item.title.rendered}</div>
)}

Now, your map callback assigns an index to each <div> and all is well with the world.

Upvotes: 1

Related Questions