I have built an infinite scroll in reactjs where the data is being loaded from the same API as the user hit the bottom of the page. Now, the problem here is to get the data from multiple different API to fetch other data.So, what would be the right way to achieve this.Please help me out with this.Here is my code.
import React from "react";
import { Link } from 'react-router-dom';
import axios from 'axios';
const BUSY = {};
class InfiniteData extends React.Component{
constructor(props){
super(props);
this.state={
olddata: [],
newData: [],
requestSent: false,
scrollCounter:1
}
this.handleOnScroll = this.handleOnScroll.bind(this)
this.buildData = this.buildData.bind(this)
}
componentDidMount(){
window.addEventListener('scroll', this.handleOnScroll);
this.doQuery(1).then(res=>
this.setState({
newData: this.state.newData.slice().concat(res),
requestSent: false
}))
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleOnScroll);
}
queryActive = false;
doQuery(queryParam) {
if(this.queryActive){
return Promise.resolve(BUSY);
}
this.queryActive=true;
switch(queryParam){
case 1: return this.buildData(queryParam).then((res)=>res).catch(err=>{})
break;
case 2: return this.buildData(queryParam).then((res)=>res);
break;
case 3: return this.buildData(queryParam).then((res)=>res);
break;
case 4: return this.buildData(queryParam).then((res)=>res);
break;
default: return true;
}
}
buildData(queryParam){
//there is no paging in getting posts, won't it just get the same posts?
return axios.get("https://jsonplaceholder.typicode.com/posts")
.then( res=> {this.queryActive=false;return res.data;})
.catch(err=>{
this.queryActive=false;
return Promise.reject(err);
})
}
handleOnScroll(){
var scrollCounter=0;
var scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
var scrollHeight = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;
var clientHeight = document.documentElement.clientHeight || window.innerHeight;
var scrolledToBottom = Math.ceil(scrollTop + clientHeight) >= scrollHeight;
if (scrolledToBottom) {
this.setState({
scrollCounter: this.state.scrollCounter + Math.floor(scrolledToBottom)
})
if(this.state.scrollCounter<5){
this.doQuery(this.state.scrollCounter).then(res=>
(res===BUSY)
? false
: this.setState({
newData: this.state.newData.slice().concat(res)
})
)
.catch(err=>this.setState({requestSent: false}))
this.setState({requestSent: true});
}else{
return true
}
}
}
render()
{
return (
<div>
<div className="data-container">
<div className="row ">
{this.state.newData && this.state.newData.map((dat,i)=>
<div key={i} className="col-lg-4">
<div className="bordered">
{dat.body}
</div>
</div>
)}
</div>
</div>
</div>
);
}
}
export default InfiniteData;
doQueryfunction should be responsible for fetching from various APIs; you can pass arguments to it to control which API to fetch from. I see this as a valid next little step towards your goal. Is there anything else that blocks or anyhow limits you in doing that? Side-note:Array#concatis non-destructive, so no need to precede it withArray#slice.doQuery().And based on the parameter ,switch the axios get request? Please help me