8

I'm writing a component that will make fetch requests to two different paths of a site, then set its states to the resulting response data. My code looks something like this:

export default class TestBeta extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            recentInfo: [],
            allTimeInfo: []
        };
    }

    componentDidMount(){
        Promise.all([
            fetch('https://fcctop100.herokuapp.com/api/fccusers/top/recent'),
            fetch('https://fcctop100.herokuapp.com/api/fccusers/top/alltime')
        ])
        .then(([res1, res2]) => [res1.json(), res2.json()])
        .then(([data1, data2]) => this.setState({
            recentInfo: data1, 
            alltimeInfo: data2
        }));
    }

However, when I go to render my two states, I find that they are actually still empty, and in fact have not been set to anything. I feel like I might be using either the Promises or fetch() API wrong, or misunderstanding how setState works, or a combination of things. I tested around and found that after the first then(), my data1 and data2 were still Promises for some reason, and had not become actual JSON objects yet. Either way, I cannot figure out for the life of me what's going on here. Any help or explanation would be appreciated

3
  • 3
    You will need to do a Promise.all on the res.json() as well as that also returns a promise. Currently your second then() block is never processed Commented Apr 10, 2018 at 13:01
  • so would it be: Promise.all([...]).then(Promise.all([res1, res2] => ...).then(Promise.all([data1, data2]) => ...)? Commented Apr 10, 2018 at 13:04
  • Yes Promise.all([res1.json(), res2.json()]) Commented Apr 10, 2018 at 13:06

1 Answer 1

21
export default class TestBeta extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            recentInfo: [],
            allTimeInfo: []
        };
    }

    componentDidMount(){
        Promise.all([
            fetch('https://fcctop100.herokuapp.com/api/fccusers/top/recent'),
            fetch('https://fcctop100.herokuapp.com/api/fccusers/top/alltime')
        ])
        .then(([res1, res2]) => Promise.all([res1.json(), res2.json()]))
        .then(([data1, data2]) => this.setState({
            recentInfo: data1, 
            alltimeInfo: data2
        }));
    }

If you return Promise in then handler, then it's resolved to value. If you return anything else (like Array in your example), it will be passed as is. So you need to wrap your array of promises to Promise.all to make it Promise type

Sign up to request clarification or add additional context in comments.

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.