Reputation: 95
I have the following code where i fetch data from twitter API feed. I use a call back function and setState the values to my state properties. When I use it in render to just console and see the value then it shows
"Cannot read property 'created_at' of undefined".
I think it is trying to fetch before it is even available. I don't know what to do here. Can someone please help.
When i use console.log(this.state.twitterfeed.techcrunch[0])
I do not get any error.
I got the object
But when I use console.log(this.state.twitterfeed.techcrunch[0].created_at)
then I got error
class Columns extends Component {
constructor() {
super();
this.state = {
twitterfeed: {
techcrunch: [],
laughingsquid: [],
appdirect: []
}
};
}
updateTwitterFeed = (data, user) => {
var twitterfeed = { ...this.state.twitterfeed };
if (user === "appdirect") {
twitterfeed.appdirect = data;
} else if (user === "laughingsquid") {
twitterfeed.laughingsquid = data;
} else {
twitterfeed.techcrunch = data;
}
this.setState({ twitterfeed });
};
componentDidMount() {
fetch(
"http://localhost:7890/1.1/statuses/user_timeline.json?count=30&screen_name=techcrunch"
)
.then(response => response.json())
.then(data => this.updateTwitterFeed(data, "techcrunch"));
fetch(
"http://localhost:7890/1.1/statuses/user_timeline.json?count=30&screen_name=laughingsquid"
)
.then(response => response.json())
.then(data => this.updateTwitterFeed(data, "laughingsquid"));
fetch(
"http://localhost:7890/1.1/statuses/user_timeline.json?count=30&screen_name=appdirect"
)
.then(response => response.json())
.then(data => this.updateTwitterFeed(data, "appdirect"));
}
render() {
return (
<div className="container mx-0">
<div className="row">
<div className="col-4 col-md-4">
{console.log(this.state.twitterfeed.techcrunch[0].created_at)}
<Column tweet={this.state.twitterfeed.techcrunch} />
</div>
</div>
</div>
);
}
}
Upvotes: 2
Views: 2133
Reputation: 1752
I have a couple of recommendations here.
First of all, try to consolidate your fetch logic using Promise.all.
Take a look at the documentation here. This will make
fetch(..).then(..)
fetch(..).then(..)
fetch(..).then(..)
into
Promise
.all([fetch(..), fetch(..), fetch(..)])
.then(...) // all 3 responses here
Also when rendering a React component componentDidMount() runs after render(). Take a look at react lifecycle here.
So the solution to be sure that the data you want to render is available is to have a flag on state such as:
this.state = { loading: True, ... } // constructor
Promise
.all([...])
.then(...)
.then(args =>
this.setState({loading: False});
...) // componentDidMount()
render() {
if(this.state.loading)
return <div>Loading...</div>
return (
// your component with data already set into the state :)
)
}
Upvotes: 0
Reputation: 112807
this.state.twitterfeed.techcrunch[0]
will be undefined
before your fetch is complete, so trying to access created_at
on that will give rise to your error.
You could e.g. render null
until the techcrunch
array has been filled after the request.
class Columns extends Component {
// ...
render() {
const { techcrunch } = this.state.twitterfeed;
if (techcrunch.length === 0) {
return null;
}
return (
<div className="container mx-0">
<div className="row">
<div className="col-4 col-md-4">
<Column tweet={techcrunch} />
</div>
</div>
</div>
);
}
}
Upvotes: 6