0

I'm dealing with a JSON response that is coming from an API. The ResponseJson contains information about a category; the responseJson.name contains a category name (tested in the console). Now I want to add all category names and store them in the empty array, categoryNames. After the for loop, the categoryNames turns out to be empty when I try to print it in the console, and I'm not sure what I'm missing. Here is the code:

_getCategories = item => {
    const categoryNames = [];
    for (let category of item.categories) {
      fetch('http://54.168.73.151/wp-json/wp/v2/categories/' + category)
        .then(response => response.json())
        .then(responseJson => {
          var categoryName = responseJson.name;
          categoryNames.push(categoryName);
        })
        .catch(error => {
          this.setState({
            isLoading: false,
            isError: true,
          });
          console.error(error);
        });
    }
    console.log(categoryNames);
  };

This questions has been identified as a possible duplicate of another question, but the answers are the other question is about a $ajax call, while I am trying to use pure JavaScript. Are there any solutions with this syntax?

MJM
  • 141
  • 1
  • 2
  • 11
  • This is async call and you should wait after all "fetch" calls are completed then categoryNames should contain all the name – Duong Dang Oct 05 '18 at 15:41
  • While the duplicate question uses a different syntax, the fundamentals are the same - `fetch` is async, and the for-loop is not waiting for the response to continue. When `console.log(categoryNames)` is called, none of your responses have completed, so the array remains empty. Instead of doing a for-loop, you can follow one of many examples for [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all), or awaiting a series of async calls. – chazsolo Oct 05 '18 at 15:41

1 Answers1

0
_getCategories = item => {
  const categoryNames = [];
  let  fetches = [];
  for (let category of item.categories) {
    fetches.push(fetch('http://54.168.73.151/wp-json/wp/v2/categories/' + category));
  }

  Promise.all(fetches).then(res => {
    /* do your stuff here */
  })
};

You should you Promise.all to wait all fetches are done. Can you try above code?

Duong Dang
  • 349
  • 1
  • 10
  • I've been trying this solution, but the array still turns out to be empty at the end. I used the line `categoryNames.push(res.name);` in the `Promise.All(fetches)`, and try to print the array after that. – MJM Oct 05 '18 at 16:20
  • Can you post your code? – Duong Dang Oct 05 '18 at 16:21
  • `_getCategories = item => { const categoryNames = []; let fetches = []; for (let category of item.categories) { fetches.push( fetch('http://54.168.73.151/wp-json/wp/v2/categories/' + category) ); } Promise.all(fetches).then(res => { categoryNames.push(res.name); }); console.log(categoryNames); };` – MJM Oct 05 '18 at 16:25
  • @MJM well, you should console log the res inside the callback. Because the Promise is async and it executes after the console.log(categoryNames); – Duong Dang Oct 05 '18 at 16:28
  • 'res' does not contain the data I need, only headers and information about the call. – MJM Oct 05 '18 at 16:52