1

I have a section class which creates a section . I'm using pizzaMenu class to render each pizza item from data.json file on UI. The code seems correct to me and should render the pizza items but it doesn't. Following is the code.
I get <div id = "app">undefined</div> when I inspect.

Link: https://codesandbox.io/embed/dazzling-robinson-bsn5g?fontsize=14&hidenavigation=1&theme=dark

App.js

class App {
  static pizzaMenu = new pizzaMenu();

  static init() {
    const app = document.getElementById("app");
    app.append(this.pizzaMenu.render());
  }
}
App.init();

pizzaMenu.js

class pizzaMenu extends Section {
  constructor(title) {
    super();
    this.title = title || "Loading...";
  }
  render() {
    const pizzaMenuEl = this.createSection();
    fetch("./data.json")
      .then((response) => {
        console.log("Check 1");
        return response.json();
      })
      .then((data) => {
        data.pizza.forEach((item) => {
          console.log("Check 2");
          pizzaMenuEl.innerHTML = `
                <div class="shop-item" id = ${item.id} >
                    <span class="shop-item-title">${item.name}</span>
                    <span class="shop-item-img"></span>
                    <div class="shop-item-details">
                        <div class = "shop-item-sizes">
                            <input type="radio" value="100" name="sizes">
                            <label>Small</label>
                            <input type="radio" value="200" name="sizes">
                            <label>Medium</label>
                            <input type="radio" value="300" name="sizes">
                            <label>Large</label>
                        </div>
                        <span class="shop-item-price">Rs.${item.price}</span>
                        <button class="btn btn-primary shop-item-button">ADD TO CART</button>
                    </div>
                </div>`;
          return pizzaMenuEl;
        });
      });
  }
}

section.js

class Section {
  // Classes must be passed as an array
  createSection(cssClasses) {
    const sectionEl = document.createElement("div");
    sectionEl.classList.add("row");

    if (cssClasses) {
      for (const cssClass of cssClasses) {
        sectionEl.classList.add(cssClass);
      }
    }

    return sectionEl;
  }
}

index.html

    <body>
        <div id="app"></div>
        <script src="section.js"></script>
        <script src="pizzaMenu.js"></script>
        <script src="app.js"></script>
    </body>

Data.json

{
  "pizza": [
    {
      "id": 1,
      "name": "Tandoori Pizza",
      "image": "Images/pizza.png",
      "price": "Rs.200",
      "sizes": { "Small": 100, "Medium": 200, "Large": 300 }
    },
    {
      "id": 2,
      "name": "Veggie Supreme",
      "image": "Images/pizza.png",
      "price": "Rs.250",
      "sizes": { "Small": 100, "Medium": 200, "Large": 300 }
    }
}
Peter O.
  • 32,158
  • 14
  • 82
  • 96
Neha Chaudhary
  • 1,071
  • 4
  • 15
  • 31

1 Answers1

2

This might be because you are not returning anything from the pizzaMenu.render() function.

I have changed your code a little bit to make it work.

Check out this repl I made https://replit.com/@beesperester/RichBelovedApplicationstack

app.js

class App {
    static init() {
        const pizzaMenuInstance = new pizzaMenu();

        const app = document.getElementById("app");
        
        // pass the app dom node to the render function
        pizzaMenuInstance.render(app)
    }
}

App.init();

pizzaMenu.js

class pizzaMenu extends Section {
    constructor(title) {
        super();
        this.title = title || "Loading...";
    }
    render(app) {
        fetch("menu.json")
        .then((response) => {
            console.log("Check 1");
            return response.json();
        })
        .then((data) => {
            data.pizza.forEach((item) => {
                // create a new div element for every item
                const pizzaMenuEl = this.createSection();

                console.log("Check 2");
                pizzaMenuEl.innerHTML = `
                    <div class="shop-item" id="${item.id}">
                        <span class="shop-item-title">${item.name}</span>
                        <span class="shop-item-img"></span>
                        <div class="shop-item-details">
                            <div class = "shop-item-sizes">
                                <input type="radio" value="100" name="sizes">
                                <label>Small</label>
                                <input type="radio" value="200" name="sizes">
                                <label>Medium</label>
                                <input type="radio" value="300" name="sizes">
                                <label>Large</label>
                            </div>
                            <span class="shop-item-price">Rs.${item.price}</span>
                            <button class="btn btn-primary shop-item-button">ADD TO CART</button>
                        </div>
                    </div>`;

                // use the method "appendChild" of the app instance
                // to append the child element
                app.appendChild(pizzaMenuEl)
            });
        });
    }
}
  • Thanks for answering. I got an error after trying your suggestion. TypeError: Illegal invocation at pizzaMenu.js:33 at Array.forEach () at pizzaMenu.js:14 – Neha Chaudhary Apr 29 '21 at 11:50