0

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));
} 
4
  • 1
    Perhaps add where the function is called? Commented Dec 19, 2019 at 23:45
  • 3
    It looks like you're logging outside of the fetch return. The data is not yet available. Move the log statement inside the final then clause. Commented Dec 19, 2019 at 23:45
  • Thanks for the input, I have accepted answer and upvoted both your input. Commented Dec 19, 2019 at 23:54
  • Are you sure my answer is not correct? Do you see an undefined being logged? Commented Dec 20, 2019 at 10:49

3 Answers 3

1

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))
Sign up to request clarification or add additional context in comments.

1 Comment

Yep. If you try to log this.state.data outside of the callback, it will often come up with the previous result since this.setState is asynchronous by nature.
0

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);
        })

} 

3 Comments

Logging in the last then like that is a race-condition since setState doesn't return a Promise.
Ok, but the bigger problem is more about the insane race condition of logging before the fetch has retuned. If anything you need to have a combination of both
Logging before the fetch is not a race-condition, it just won't work at all.
0

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)}));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.