Justin
Justin

Reputation: 1479

Create HTML elements from nested array

I am attempting to create the mobile view of a restaurant menu. The menu itself is stored in the menu variable which holds data in the form of

let menu = [
  [
    'Food Section', //i.e Appetizers
    ['Entry', 'Food Description' , 'Price'],
    ['Entry', 'Food Description' , 'Price']

  ]
  [
    'Food Section', //i.e Soup
    ['Entry', 'Food Description' , 'Price'],
    ['Entry', 'Food Description' , 'Price']
  ],
   etc...

I want the website itself to display buttons with the food sections ("Appetizers" button, "Soup" button) and upon clicking said button the appropriate food entries will drop down and become visible. For now I am attempting to just create the buttons and divs of the appropriate entries under each button. I do this by looping through menu and then looping through each menu element. Here is my code: js:

let menu = [
  [
      'Appetizers',
      ['Fried Calamari', "", '$11.95'],
      ['Mussels', "Marinara, fra diavolo or bianco", '$12.95'],
      ['Calamari & Mussels', "Fra diavolo or marinara", '$12.95'],
      ['Hot Antipasto', "Two baked clams, two stuffed shells, two stuffed mushrooms, two fried shrimp & scallops in a seafood sauce", '$14.95'],
    ],
    [
      'Soups',
      ['Chicken Noodle','','$4.95'],
      ['Minestrone','','$4.95'],
      ['Lentil','','$5.95'],
      ['Pasta Fagioli','','$5.95'],
      ['Cheese Tortellini','','$6.95'],
    ]



//create html elements by looping through menu variable
      for(i = 0; i < menu.length; i++){
        for(j = 0; j < menu[i].length; j++){
          if(j == 0){
            foodSectionText = menu[i][j];
            let btn = document.createElement("BUTTON");
            btn.innerHTML = foodSectionText;
            document.body.appendChild(btn);      }
          else{
            menuEntry = menu[i][j];
            console.log(menuEntry);
            for(i = 0; i < menuEntry.length; i++){
              div = document.createElement("DIV");
              div.innerHTML = menuEntry[i];
              document.body.appendChild(div);
            }
          }
        }
      }

The above code will create:

<button>Appetizers</button>
<div>Fried Calamari</div>
<div></div>
<div>$11.95</div>

But then throws Uncaught TypeError: Cannot read property 'length' of undefined referring to for(j = 0; j < menu[i].length; j++). Why is the second item ['Mussels', "Marinara, fra diavolo or bianco", '$12.95'] (and all subsequent items) not being properly rendered? Also if you have any suggestions as to how to clean up this process feel free to share, I feel I am going about implementing this a terrible way...

Upvotes: 0

Views: 244

Answers (1)

Atsushi
Atsushi

Reputation: 361

In the 3rd for loop, you're reusing the same loop counter i. Try using a different variable name (in my example I used k)

for(let i = 0; i < menu.length; i++){
  for(let j = 0; j < menu[i].length; j++){
    if(j == 0){
      foodSectionText = menu[i][j];
      let btn = document.createElement("BUTTON");
      btn.innerHTML = foodSectionText;
      document.body.appendChild(btn);      }
    else{
      menuEntry = menu[i][j];
      console.log(menuEntry);
      for(let k = 0; k < menuEntry.length; k++){
        div = document.createElement("DIV");
        div.innerHTML = menuEntry[k];
        document.body.appendChild(div);
      }
    }
  }
}

Upvotes: 1

Related Questions