Reputation: 1080
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
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
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