0

I'm trying to get a JSON array of objects with a for loop but for some reason it only works if I pass the index explicitly as a number (e.g. parseJSON.sites[0]). If I use a variable, which I would prefer in this example because of the loop, the shown example doesn't work.

let openJSON = fs.readFileSync('./pages/jsons/main.json', 'utf-8');
let parseJSON = JSON.parse(openJSON);
for (let i = 0; i <= 4; i++) {
    //this code doens't work and return: Cannot read property 'name' of undefined          
    main.push(parseJSON.sites[i]["name"]);

    //this code works, and returns what i expected
    main.push(parseJSON.sites[0]["name"]);
}


//main.json
{
    "sites": [
        { "name": "stackoverflow", "url": "stackoverflow.com" },
        { "name": "Youtube", "url": "www.youtube.com" },
    ]
}

I have no idea why this code doesn't work. I already tried to change the name of the variable i, in case of any conflict but it still returns the same error. I also tried to execute the code snippet without the .push() method.

8
  • 2
    You need to provide a minimal reproducible example. Fragments of code that throw syntax errors when you try to run them don't really help anyone solve your problem. Commented Jun 16, 2019 at 20:06
  • 1
    Bellow the for loop is my json file (i forget to comment that) Commented Jun 16, 2019 at 20:07
  • 1
    @quentin the function is the for loop and opening and parsing json, in this case the max i could add is this: let openJSON = fs.readFileSync('./pages/jsons/main.json', 'utf-8'); let parseJSON = JSON.parse(openJSON); and the code bellow the loop is what is written in my json file Commented Jun 16, 2019 at 20:11
  • 1
    Well, then that is invalid JSON. And you don't show how it gets into the parseJSON variable. Commented Jun 16, 2019 at 20:11
  • 1
    Edit the question to show a minimal reproducible example Commented Jun 16, 2019 at 20:12

1 Answer 1

2

The problem here is obviously the loop. While the sites array in your JSON object from the main.json file only contains two entries, your loop makes four iterations. This means, that the JavaScript interpreter (keep in mind its interpreted at runtime) throws the error at the third loop where it cannot find any property name for the third element in the sites array as there simply is no third element (i.e. JSON object).

Solution 1: You can limit the iterations of the loop to the length of the sites array by changing the condition of the for loop like this:

let main = []
let openJSON = fs.readFileSync('./main.json', 'utf-8');
let parseJSON = JSON.parse(openJSON);

for(let i = 0; i < parseJSON.sites.length; i++){ 
    main.push(parseJSON.sites[i]["name"]);
}

Solution 2: If the number of iterations needs to stay at a fixed length (e.g. 4 like in your example), you can catch the error with a try-catch block. Check out the example below.

let main = []
let openJSON = fs.readFileSync('./main.json', 'utf-8');
let parseJSON = JSON.parse(openJSON);

for(let i = 0; i <= 4; i++){ 
    try {
      main.push(parseJSON.sites[i]["name"]);
    } catch (TypeError) {
      // handle TypeError
      console.log(`No property 'name' found for entry at index ${i}`)    
    }
}

Solution 3: While the try-catch solution (i.e. Solution 2) is working, it may be too much for the given scenario as stated by Julian. Therefore, I have included the following solution that checks if the sites array at index i has an entry or is undefined. Note that I included two possibilities in this solution.

let main = []
let openJSON = fs.readFileSync('./main.json', 'utf-8');
let parseJSON = JSON.parse(openJSON);

for(let i = 0; i <= 4; i++){
    // declare current entry (for readability)
    const currEntry = parseJSON.sites[i]

    // checking if there is an i-th entry in sites
    if (currEntry) {
      main.push(currEntry["name"]);
    }

    // same solution, more compact approach
    currEntry ? main.push(currEntry["name"]) : null
}
Sign up to request clarification or add additional context in comments.

5 Comments

I think checking for undefined in your second solution is better than a try-catch
@Julian Yes you can also check for undefined. My second solution was just a quick example but there are multiple ways on how to solve this issue.
Yes there are multiple solutions. You could also do while(2<3) instead of while(true). But not all solutions are nice. I think this is a really bad example for using a try-catch.
@Julian You are right. Using a try-catch block for this scenario is not the best approach. Therefore, I have added a third solution that checks for undefined. Thank you for the feedback!
Thanks, I think it's important to not learn new ones to overuse try-catches (image the number 4 is 1000 ...). You got my upvote :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.