Reputation: 5619
in my reactjs app I do this:
constructor(props) {
super(props);
this.state = {
myTasks: tasksData,
processes: []
};
}
componentWillMount() {
fetch('http://localhost:9000/dashboard/processes')
.then(function (response) {
return response.json()
}).then(function (json) {
this.setState({processes: json});
}.bind(this)).catch(function (ex) {
console.log(ex)
});
}
Problem is that the render method is run bevor this and the json data isn't there right bevor the table is rendered
<BootstrapTable
react- data={this.state.processes}
search={true}
options={options}
striped hover condense
pagination={true}>
<TableHeaderColumn width='200' dataField='process' searchable={true} isKey><T value="dashboard.processes.process"/></TableHeaderColumn>
<TableHeaderColumn width='100' dataField='status'><T value="dashboard.processes.status"/></TableHeaderColumn>
<TableHeaderColumn width='100' dataField='progress' dataFormat={progressBarFormatter}><T value="dashboard.processes.progress"/></TableHeaderColumn>
<TableHeaderColumn width='100' dataField='deadline'><T value="dashboard.processes.deadline"/></TableHeaderColumn>
</BootstrapTable>
SO i got this error:
TypeError: Cannot read property 'process' of undefined at TableBody.eval (eval at ./node_modules/react-bootstrap-table/lib/TableBody.js (http://localhost:8080/bundle.js:3702:1), :199:32) at Array.map (native) at TableBody.eval (eval at ./node_modules/react-bootstrap-table/lib/TableBody.js (http://localhost:8080/bundle.js:3702:1), :198:47) at Array.map (native) at TableBody.render (eval at ./node_modules/react-bootstrap-table/lib/TableBody.js (http://localhost:8080/bundle.js:3702:1), :197:39) at TableBody.render (eval at ./node_modules/react-proxy/modules/createPrototypeProxy.js (http://localhost:8080/bundle.js:5252:1), :46:30) at eval (eval at ./node_modules/react-dom/lib/ReactCompositeComponent.js (http://localhost:8080/bundle.js:4238:1), :798:21) at measureLifeCyclePerf (eval at ./node_modules/react-dom/lib/ReactCompositeComponent.js (http://localhost:8080/bundle.js:4238:1), :77:12) at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (eval at ./node_modules/react-dom/lib/ReactCompositeComponent.js (http://localhost:8080/bundle.js:4238:1), :797:25) at ReactCompositeComponentWrapper._renderValidatedComponent (eval at ./node_modules/react-dom/lib/ReactCompositeComponent.js (http://localhost:8080/bundle.js:4238:1), :824:32)
How can I solve this?
Upvotes: 0
Views: 944
Reputation: 5645
Load your data in a parent container component. If the container doesn't have data, render a loading element. When the data arrives, update the container components state with the data to render the child component with data. It's always a good idea to separate your concerns between container components for data fetching and state control, and presentational components to handle the visual aspects of the application. Take a look at Presentational and Container Components by Dan Abramov.
import React, { Component } from "react";
export default class Container extends Component {
constructor(props) {
super(props);
this.state = {
processes: null
};
}
componentDidMount() {
fetch('http://localhost:9000/dashboard/processes')
.then(function (response) {
return response.json()
}).then(function (json) {
this.setState({processes: json});
}.bind(this)).catch(function (ex) {
console.log(ex)
});
}
render() {
return (
this.state.processes ?
<div class="loading">Loading data...</div> :
<BootstrapTable
react-data={this.state.processes}
search={true}
options={options}
striped hover condense
pagination={true} />
);
}
}
Upvotes: 0
Reputation: 5619
solution for me is to do this:
if(this.state.processes.length === 0) return <p>Bitte warten sie ...</p>;
return (
Upvotes: 0
Reputation: 361
Render is called after component will mount (see: https://stackoverflow.com/a/37123901/5813839). The problem here is a race condition. You fetch the json and asynchronously wait for the response, meanwhile render is called and breaks.
The fix is to allow your component to run without the json data present (blank or temporary holding values) and then as soon as the json is loaded into your state react will execute render again and update your component.
Upvotes: 1