Thidasa Pankaja
Thidasa Pankaja

Reputation: 1080

How to make to make sequential async calls and pass data to a sibling component properly?

I'm trying to build a hackernews clone as a practice to reactjs. Here I'm trying to build this only with react and later I'm going to build this with Redux. This is my component structure.

--main
  |--menubar
  |--articles

Here is the codepen for the project.

I'm having two issues here.

1.) Here I'm passing data through state and props.I'm calling the API in componentDidMount method on menubar component and pass it to the articles component through main component. But it doesn't render the list when it receives the data through props in componentWillReceiveProps method. To render it I have to click News (which has no connection with fetching data, it's just printing a log) which will recall the API method. How can I render the data in this.state.articleList when the data is received through props and set the data.

2.) In the API call, I have defined to get first 20 posts only. But when I click news, I'm getting random number of (<20) posts rendered in each time. Why is that ? As the API call is same, shouldn't it render same amount of(20) posts ? Why it differ ?

Is the both issues because of Asynchronous methods ? If so how can I solve them ?

Upvotes: 0

Views: 1325

Answers (2)

Akhilesh krishnan
Akhilesh krishnan

Reputation: 799

Actually its because of async, i edited it using the async library edited the fetchdata() and added getItems().

The advantage of using map is that it will return an array of results itself so we need not maintain an array.

var async = require("async");

fetchdata() {
fetch("https://hacker-news.firebaseio.com/v0/topstories.json")
  .then(res => res.json())
  .then(data => {
    this.setState({ storyList: data }, () => {
      this.getItems(this.state.storyList);
    });
  })
  .catch(err => console.log(`Error fetching data : ${err}`));
  }


getItems(storyList) {
    async.mapLimit(storyList, 10,
      function(item, callback) {
        console.log(item);
        fetch(`https://hacker-news.firebaseio.com/v0/item/${item}.json`)
          .then(res => res.json())
          .then(data => {

            //pass the data here
            callback(null, data);
          });
      },
      function(err, dataArray) {
        if (err) {
          console.error(err.message);
        } else {

          //dataArray will contain an array of results from map
          this.props.getData(dataArray);
        }
      }
    );
  }

Upvotes: 1

Venkatesh Chitluri
Venkatesh Chitluri

Reputation: 31

Hi after getting the data inside getItems binding the data to callback getData as follows

getItems(storyList) {
    var story_list = [];
    async.mapLimit(
        storyList,
        10,
        ((item, callback) =>{
            console.log(item);
            fetch(`https://hacker-news.firebaseio.com/v0/item/${item}.json`)
                .then(res => res.json())
                .then(data => {
                    story_list.push(data);
                    this.props.getData(story_list);
                });
        }),
            ((err) =>{
            if (err) {
                console.error(err.message);
            } else {
                this.props.getData(story_list);
            }
        })
    );
}

Upvotes: 1

Related Questions