Sole
Sole

Reputation: 3340

Cannot console log api results in React

This could be the simplest thing, but my console log below is not working to see the api results, can anyone see why, I am new to React BTW.

componentDidMount() {
    this.setState({ loading: true })
    console.log('app mounted');
    fetch('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=8')
        .then(data => data.json())
        .then(data => this.setState({ data: data.articles, loading: false}))
        console.log('Results -', JSON.stringify(this.data));
} 

Upvotes: 0

Views: 969

Answers (3)

Rakesh Jain
Rakesh Jain

Reputation: 235

Your console.log('Results -', JSON.stringify(this.data)); is executing even before the data is returned.

So to console log the result:

put console.log as a callback to setState, since it is an asynchronous function:

fetch('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=8')
        .then(data => data.json())
        .then(data => this.setState({ data: data.articles, loading: false}, () => {'Results -', JSON.stringify(data)}));

Upvotes: 0

Lukas
Lukas

Reputation: 10340

So the first thing you need to know I that you are working with Promises here. Promises are asynchronous, which means if you would write these lines of code

let a = "a"

fetch('https://newsapi.org/...')
  .then(() => { a = "b"; }

console.log(a) // "a"

The result would be a because JavaScript will start whatever is creating a Promise (in this case fetch) and then go on with the lines following that (in this case console.log(a)). The .then parts will be executed when the promise has finished whatever it is doing, in your case waiting for the network traffic to come back.

So what happens in your case is

// You set the state
this.setState({ loading: true })

// You log
console.log('app mounted');

// You create a promise
fetch('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=8')
    // all of these then things will be called when the network traffic finishes
    .then(data => data.json())
    .then(data => this.setState({ data: data.articles, loading: false}))

    // this line is not part of the then so this is what actually gets called next
    // so here you are still logging the original state of this.data not the one after the network traffic
    console.log('Results -', JSON.stringify(this.data));


    // some time in the future your thens will be executed

Also the second thing here is that you are logging this.data. You actually want to log this.state.data. So your code should look like this

componentDidMount() {
    this.setState({ loading: true })
    console.log('app mounted');
    fetch('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=8')
        .then(data => data.json())
        .then(data => this.setState({ data: data.articles, loading: false}))
        .then(() => {
            console.log('Results', this.state.data);
        })

} 

Upvotes: 0

seanulus
seanulus

Reputation: 885

You can log the results in the callback of the setState function like this:

this.setState({ data: data.articles, loading: false}, () => console.log(data.articles))

Upvotes: 1

Related Questions