I need to click twice on a button linked to the current page so i can get the data fetched from the api to render. I am using nivo / charts to visualize my data.
The component fetches the company list from the api, and a second fetch loops through every result fetching data for every distinct company.
On first try, the company list were to fetch on the parent component, and a fetch request would take place for every child component thereafter
(parent=list of chart components, child=Company Chart)
, but on the pagination process it did not render properly so I had to uplifted the state to the parent component, the problem this time was that the parent component did not render on first click, I had to double click for example link button so that the parent component would render.
I thought the problem might be occurring since there might had been a missynchronization with the componentDidMount order of actions since I was sure that the first and second data fetching (first being the company get request and second distinct company get request), were executing simultaneously rather than one after the other. So I directed to redux and architectured my application to redux rules. It did not resolve anything and still requires to double click on a link so that the rendering would take place.
Now I feel like I would need to add some await/async rules for the api fetching process but I am not sure whether that would work or not, so I would really appreciate getting a second opinion on how to solve this little problem because it has been bugging me for weeks.
my Reducer:
import { FETCH_COMPANIES } from '../actions/types';
const initialState = {
next : null,
prev : null,
items : [],
item : [],
}
export default function(state = initialState, action) {
switch (action.type) {
case FETCH_COMPANIES:
return {
...state,
items : action.payload.companies,
next : action.payload.next,
prev : action.payload.prev,
}
default:
return state;
}
}
my Store.js:
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware)
)
)
export default store;
my Actions:
import axios from 'axios';
import { FloatType } from 'three';
import { FETCH_COMPANIES } from './types';
export const fetchAllData = (url) => dispatch => {
fetch(url)
.then(res => res.json())
.then(
posts =>
dispatch({
type : FETCH_COMPANIES,
payload : FetchCall(posts),
})
)
}
function FetchCall(res) {
let next;
let prev;
try {
next = res.next;
}
catch(err) {
console.log(err)
}
try {
prev = res.previous;
}
catch(err) {
console.log(err)
}
const CompanyArray = Array()
res.results.map(element => {
axios.get(`https://API/${element.symbol}/`).then((res) => {
const DataGroup = handleChartData(res.data)
CompanyArray.push({
'name' : element.symbol,
'data' : DataGroup,
})
})
});
const ALL_DATA = {
'next' : next,
'prev' : prev,
'companies' : CompanyArray,
}
return ALL_DATA;
}
function handleChartData(data) {
DataGroup = Object()
return DataGroup;
}
And my Component:
import React, { useState} from 'react';
import { Card, Row, Col, Button } from 'antd';
import Chart from '../components/Chart';
import DetailCompany from './CompanyDetail';
import { connect } from 'react-redux';
import { fetchAllData } from '../actions/chartActions';
import PropTypes from 'prop-types';
class CompanyList extends React.Component {
constructor(props) {
super(props);
this.state = {
charts : this.props.charts
}
}
componentWillMount() {
try {
this.props.fetchAllData("https://API/company/")
}
catch(err) {
console.log(err)
}
};
prevPage = () => {
let toPage = this.props.prev
this.props.fetchAllData(toPage)
}
nextPage = () => {
let toPage = this.props.next
this.props.fetchAllData(toPage)
}
render() {
const chartItems = this.state.charts.map(chart => (
<Col style={{margin:'0 0 75px 0'}} span={12} key={chart.name}>
<h1 style={{lineHeight:'2em', margin:'0 0 0 70px'}}>{chart.name}</h1>
<div className="chart-block">
<Chart symbol={chart.name}
data={chart.data.chartData}
>
</Chart>
</div>
</Col>
));
return (
<Card>
<Row>
{chartItems}
</Row>
<Row>
<Button disabled={(this.props.prev ? false : true )} onClick={() => {this.prevPage()}}>Previous</Button>
<Button onClick={() => {this.nextPage()}}>Next</Button>
</Row>
</Card>
)
}
}
CompanyList.propTypes = {
fetchAllData : PropTypes.func.isRequired,
charts : PropTypes.array.isRequired,
}
const mapStateToStore = state => ({
prev : state.charts.prev,
next : state.charts.next,
charts : state.charts.items,
});
export default connect(mapStateToStore, { fetchAllData })(CompanyList);
I would genuinely appreciate if anyone could help me to get around this problem and understand it to prevent further misdirection or reoccurrence. Thank you.