0

To start things off, I'm fairly new to coding and JS, so maybe I'm misunderstanding something very basic here.

I built a script to check a .JSON file for any fields named "ID: XXXX". Its purpose is to return every article's unique identifier from a blog. The unique identifier is "XXXX" in this case.

The script does what it's supposed to, but when I return the values to my global variable article_identifiers, they're returned as a pseudo array. I can't access single values by indexing them via article_identifiers[i].

However, when I set a timeout, article_identifiers is returned as a normal array and I can access the values inside the array by using console.log(article_identifiers[i]).

Here's the code, for context:

var article_identifiers = [];
var url = '/articles.json';

  fetch(url)
  .then((response) => response.json())
  .then(data => {
    var article_amount = Object.keys(data.articles).length;

    for (var i = 0; i < article_amount; i++) {
    article_identifiers.push(data.articles[i].id);
    }
  })

setTimeout(function(){
    console.log(article_identifiers);
},500);

Why do I have to set a timeout? Am I misunderstanding something about the way JavaScript code is processed? Does my console.log() fire before my for loop is finished? If so, why?

Robert
  • 1
  • 1
  • Wrong structuring ? Fetch is probably async, so easiest would be to check it inside its processing function. You cannot be sure if fetch already passed or not this way. – Jan Sep 19 '19 at 09:56
  • Actually, that's the answer. Thank you, Tom! :) fetch() is an async function, so I have to put an await in there. – Robert Sep 19 '19 at 10:02

1 Answers1

0

First off, thanks for the super fast replies!

Here's the solution:

var article_identifiers = [];
var url = '/articles.json';

await fetch(url)
  .then((resp) => resp.json())
  .then(data => {
    var article_amount = Object.keys(data.articles).length;

    for (var i = 0; i < article_amount; i++) {
    article_identifiers.push(data.articles[i].id);
    }
  })

console.log(article_identifiers);

fetch() is an asynchronous function, so I just had to put an await before that.

I'll mark this one as a lesson to always check if a prebuilt function is async or not.

Thanks!

Robert
  • 1
  • 1
  • Or continue chaining it `.then(()=>console.log(article_identifiers))` – TheMaster Sep 19 '19 at 10:21
  • Does it make sense to continue chaining if I want to do something with the values stored in article_identifiers? – Robert Sep 19 '19 at 10:31
  • Depends. Do you want to wait or continue running unrelated processes during this time? – TheMaster Sep 19 '19 at 10:48
  • I want to make a post/put based on `article_identifiers`, after I got the IDs stored there. Here's the basic idea: `for (var i = 0; i < article_identifiers.length; i++) POST {"name": "NewArticle", "ID": article_identifiers[i]}` – Robert Sep 19 '19 at 12:41
  • I don't think it'll make much difference. It seems `await` is probably the best way for your flow. – TheMaster Sep 19 '19 at 13:49