3

$(function() {
  var model = {
    currentCat: null,
    cats: [{
        name: "Felix",
        clickCounter: 0,
        srcImage: "cat0.jpg"
      },
      {
        name: "Lucas",
        clickCounter: 0,
        srcImage: "cat1.jpg"
      },
      {
        name: "Martin",
        clickCounter: 0,
        srcImage: "cat2.jpg"
      },
      {
        name: "Pedro",
        clickCounter: 0,
        srcImage: "cat3.jpg"
      }
    ]
  };

  var octopus = {
    init: function() {
      indexView.init();
      displayView.init();
    },
    getCats: function() {
      return model.cats;
    },
    getCurrentCat: function() {
      return model.currentCat;
    },
    setCurrentCat: function(cat) {
      model.currentCat = cat;
    },
    updateClickCounter: function() {
      model.currentCat.clickCounter++;
      displayView.render();
    }
  };

  var displayView = {
    init: function() {
      this.imgSection = document.getElementById("imageSection");
      this.catImg = document.getElementById("cat-img");
      this.catName = document.getElementById("cat-name");
      this.catCounter = document.getElementById("cat-counter");

      this.catImg.addEventListener("click", function() {
        octopus.updateClickCounter();
      })
      this.render()
    },
    render: function() {
      var cat = octopus.getCurrentCat();

      this.catName.textContent = cat.name;
      this.catCounter.textContent = cat.clickCounter;
      this.catImg.src = cat.srcImage;
    }
  };


  var indexView = {
    init: function() {

      this.list = $("#list")
      this.render();

    },
    render: function() {
      cats = octopus.getCats();
      for (i = 0; i < cats.length; i++) {
        cat = cats[i];
        listElement = document.createElement("li");
        listElement.textContent = cat.name;

        listElement.addEventListener("click", (function(copyCat) {
          octopus.setCurrentCat(copyCat);
          displayView.render();
        })(cat));
      };
    }
  };



  octopus.init();
});
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>Cat clicker</title>
  <link rel="stylesheet" href="css/cat.css">
  <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" type="text/css" />
</head>

<body>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  <script src="js/cat.js"></script>

  <h1 id="header"> Gatitos! </h1>

  <div id="catIndex">
    <h2 id="indexTitle">Index</h2>
    <ul id="list">
      <!-- here we have the index with the cats names -->
    </ul>
  </div>
  <div id="imageSection">

    <h2 id="cat-name"></h2>
    <div id="cat-counter"></div>
    <img src="" id="cat-img">
  </div>

</body>

</html>

in the displayView object, I can only acces the html elements that I got with getElementById inside the method they were initialized in (I can acces catImg when I add the event listener in the init method). The problem comes when I try to acces those elements in the render method. When you run this it returns undefined when you call all the elements from the init method (this.catImg, this.catName and this.catCounter). Why does it return undefined?

Azad
  • 5,144
  • 4
  • 28
  • 56
  • use `document.createTextNode` to add text on created elements – Azad Dec 12 '18 at 05:09
  • @azad creating the text content is not the problem because I can't acces the element to which I would append that text node in the first place. When I try to do `this.catImg.src = cat.srcImage` it throws an error `cannot set property 'src' to undefined` – elias velardez Dec 12 '18 at 05:16
  • you are calling `displayView.render()` before `displayView.init()` in `indexView.render()` – Azad Dec 12 '18 at 05:26

1 Answers1

1

you have to bind 'this' to your event handler, check out Javascript scope addEventListener and this on how to scope this to your event listener.

MattjeS
  • 1,367
  • 18
  • 35