0
export function fetchNews(data) {
    const news = []

    var numOfArticlesArray = fetchNewsPreprocessing(data)

    data.map((interest, index) => {

        fetch(`https://newsapi.org/v2/top-headlines?country=us&category=${interest}&apiKey=`)
        .then(res => res.json())
        .then(res => res.articles)
        .then(res => {
            
            for (let i = 0; i < numOfArticlesArray[index]; i++) {
                news.push(res[i])
            }
        })
        .catch(err => console.log(err))
        
    })

    console.log(news);

}

So here is the function, my issue is that I'm getting this console.log(news); before I finish appending to my news array in here news.push(res[i]) which results in a blank array.

I tried adding async and await to the function like this async function fetchNews(data) and await data.map((interest, index) => { but no use.

thanks in advance.

Kadiem Alqazzaz
  • 554
  • 1
  • 7
  • 22
  • This answers your question [Node JS Promise.all and forEach](https://stackoverflow.com/questions/31413749/node-js-promise-all-and-foreach) – Samathingamajig Jul 13 '21 at 17:25
  • Do you want the requests to run in parallel or in sequence? (In parallel it can randomize the order in the results.) Also, why do you loop until `numOfArticlesArray[index]` and not just `res.length`? (Note that your `data.map` is also a bit misleading because it doesn't map to anything.) – CherryDT Jul 13 '21 at 17:27

2 Answers2

1

Do you want to execute your fetch() calls serially, or in parallel?

If you want to execute them serially then something like this will work:

export function fetchNews(data) {
  const news               = [];
  const numOfArticlesArray = fetchNewsPreprocessing(data);
  
  data.map( async (interest, index) => {
    const url = `https://newsapi.org/v2/top-headlines?country=us&category=${interest}&apiKey=`;
    
    try {
      const res = await fetch(url).then(res => res.json());
      const articles = res.articles;
     
      for ( let i = 0 ; i < numOfArticlesArray[index] ; i++ ) {
        news.push(articles[i]);
      }
    
    } catch (err) {
      console.log(err);
    }
        
  })

  console.log(news);

}

If you want to execute them in parallel, however, then something like this is what you want:

export async function fetchNews(data) {
  const news               = [];
  const numOfArticlesArray = fetchNewsPreprocessing(data);
  const requests           = data.map( (interest, index) => {
    const url = `https://newsapi.org/v2/top-headlines?country=us&category=${interest}&apiKey=`;
    const res = fetch(url).then(res => res.json());
    
    return res;
  })
  const responses = await Promise.all( requests );

  for ( const i = 0 ; i < responses.length ; ++i ) {
    const res = responses[i];
    const articles = res.articles;
    
    for ( let j = 0 ; j < numOfArticlesArray[i] ; ++j ) {
      news.push(articles[j]);
    }

  }

  console.log(news);

}

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
0

You should put await in front of fetch() instead. For example, this piece of code will output the news array with the test element:

async function fetchNews(data) {
  let news = [];
  await fetch(url).then(() => news.push('test'));
  console.log(news)
}
Triet Doan
  • 11,455
  • 8
  • 36
  • 69