Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Manage Multiple Requests with Promise.all

Jiten Mehta
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Jiten Mehta
Front End Web Development Techdegree Graduate 21,209 Points

Why can't i use a arrow function for the Checkstatus function?

Hey guys, question regarding the checkStatus function...

Here is how i written it initially.

const checkStatus = (response) =>{
  if(response.ok){
    return Promise.resolve(response)
  } else{
    return Promise.reject(new Error(response.statusText))
  }
}

After creating the Promise.all method i kept getting errors for the checkstatus function.

I then realized Guil has been using normal function syntax.

I then changed the checkStatus function to the following...

function checkStatus(response) {
  if(response.ok){
    return Promise.resolve(response)
  } else{
    return Promise.reject(new Error(response.statusText))
  }
}

After changing the syntax, everything started to work as expected.

Should we avoid using arrow functions altogether when working with Fetch API?

Thanks!!!

3 Answers

I had the same issue, the console gave the error code

Uncaught ReferenceError: can't access lexical declaration 'checkStatus' before initialization

The checkStatus function was set up as so

const checkStatus = (response) => {
  if (response.ok) {
   return Promise.resolve(response); 
  } else {
    return Promise.reject(new Error(response.statusText));
  }
}

However when it was changed to what it is below, it worked

const select = document.getElementById('breeds');
const card = document.querySelector('.card'); 
const form = document.querySelector('form');

// ------------------------------------------
//  FETCH FUNCTIONS
// ------------------------------------------

function fetchData(url) {
 return fetch(url)
 .then(checkStatus)
 .then(res => res.json())
 .catch(error => console.log('Error found.', error))
}

Promise.all([
fetchData('https://dog.ceo/api/breeds/list'),
fetchData('https://dog.ceo/api/breeds/image/random')
  ])
.then(data => {
  const breedList = data[0].message;
  const randomImage = data[1].message;

  generateOptions(breedList);
  generateImage(randomImage);
})

// ------------------------------------------
//  HELPER FUNCTIONS
// ------------------------------------------
function checkStatus(response) {
  if (response.ok) {
   return Promise.resolve(response); 
  } else {
    return Promise.reject(new Error(response.statusText));
  }
}

const generateOptions = (data) => {
  const options = data.map(item => `
   <option value='${item}'> ${item} </option>
`).join('');
  select.innerHTML = options
}


const generateImage = (data) => {
 let html =` 
<img src='${data}' alt>
<p>Click to view images of ${select.value}s</p>
`;
 card.innerHTML = html;
}

const fetchBreedImage = () => {
 const breed = select.value;
 const img = card.querySelector('img');
 const p = card.querySelector('p');

fetchData(`https://dog.ceo/api/breed/${breed}/images/random`)
    .then(data => {
      img.src = data.message;
      img.alt = breed;
      p.textContent = `Click to view more ${breed}`
    })
}

// ------------------------------------------
//  EVENT LISTENERS
// ------------------------------------------
select.addEventListener('change', fetchBreedImage);
card.addEventListener('click', fetchBreedImage);


// ------------------------------------------
//  POST DATA
// ------------------------------------------
Brandon White
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brandon White
Full Stack JavaScript Techdegree Graduate 35,771 Points

Piggybacking off of Jonathan Grieve, you should be fine using arrow functions with fetch. Unless Iโ€™m trying to make sure my functions are hoisted or I need this to be bound to the function, I almost exclusively use arrow functions (which includes when Iโ€™m making fetch requests).

Any chance you could share all of your code?

Brandon White
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brandon White
Full Stack JavaScript Techdegree Graduate 35,771 Points

For those that donโ€™t know what hoisted means, (in the context of this question) it essentially means that functions declared with the function keyword can be called from anywhere in that file. A function expression using const, let, or var is not hoisted. This means that the function canโ€™t be called until after its expression appears in the code. So if you create a function const newFunction = () => {/* do something */} on line 38, then you wonโ€™t be able to invoke the newFunction function before line 38. However, if you declare the same function using the function keyword (on line 38) you could call it from anywhere in that file (for instance, you could call it on line 2).

I donโ€™t know that this was the original posterโ€™s issue, but I suspect that it could have been. And seeing that it worked after changing the function expression to a function declaration gave the impression that the arrow function didnโ€™t work.

Jonathan Grieve
MOD
Jonathan Grieve
Treehouse Moderator 91,253 Points

I'm not sure why this should be the case, to tell you the truth. The only difference I can see is the function definition syntax rather than what's inside it. I haven't seen anything online after a big search that confirms your question so for ow I would simply stick with what's working for you! :-)