kennycodes
kennycodes

Reputation: 536

componentDidMount multiple fetch calls best practice?

I have a lot of APIs that are INDEPENDENT of each other and needs to be stored in the React state before it is rendered. I have fetch calls in componentDidMount but I am not sure what is the best way to approach this. Should I...

  1. have nested fetch calls

example:

componentDidMount() {
    fetch('url')
    .then((res) => res.json())
    .then((data) => {
        // call another fetch in here
    })

}

OR 2. have separate fetch calls

example:

componentDidMount() {
    fetch('url')
    .then((res) => res.json())
    .then((data) => {
        // set state in here
    })
    
    // call another fetch for the other url endpoint
    fetch('url2')
    .then((res) => res.json())
    .then((data) => {
        // set state in here
    })
}

I'm not sure if one way is considered better practice over the other, but I would love to know what you guys think and what some of the pros/cons would be.

UPDATE: I am using Promise.all() now, but I am getting the Promise returned rather than the actual value. Here is my code:

Promise.all([
  fetch(`/api/url1`),
  fetch(`/api/url2`),
])
.then(([res1, res2]) => (
  {
    res1: res1.json(),
    res2: res2.json(),
}))
.then(({res1, res2}) => {
  this.setState({
    state1: res1,
    state2: res2,
  });
})
.catch((error) => {
  console.log(error);
});

When I checked the values of my state on the console, here is what I get:

Promise
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: Array(6530)

Any idea of what I may be missing / doing wrong?

Upvotes: 5

Views: 15662

Answers (2)

Volodymyr
Volodymyr

Reputation: 1408

As far as fetch returns Promise you can use Promise.all function to execute both fetches in parallel:

componentDidMount() {
    Promise.all([fetch('url'), fetch('url2')])

      .then(([res1, res2]) => { 
         return Promise.all([res1.json(), res2.json()]) 
      })
      .then(([res1, res2]) => {
        // set state in here
      });
}

Upvotes: 12

Ivan Burnaev
Ivan Burnaev

Reputation: 2730

As @CertainPerformance mentioned, you should use Promise.all method.

Promise.all([
  fetch("url1"),
  fetch("url2"),
  fetch("url3"),
]).then(([res1, res2, res3]) => {
  this.setState({status: "fetched"})
})

const url = "https://asdqwe.free.beeceptor.com/my/api/path";

const promises = Promise.all([
  fetch(url),
  fetch(url),
  fetch(url),
]);


promises
  .then((results) => 
    Promise.all(results.map(r => r.text()))
  )
  .then(console.log)

Upvotes: 6

Related Questions