0

I need to remove some popup element from the page with a click on the button, but something is happening to the context or to the property of the object and I have absolutely no idea what is going on.

  constructor(container) {
    this._container = container;
    this._card = null;

    this._popup = null;

  }
  render(card) {
    this._card = new Card(card);

    renderComponent(this._container, this._card);

    this._card.clickCardListener(".film-card__title", "click", function () {
      this._popup = new Popup(card);

      console.log(this._popup);

**//log: Popup {_element: null, _card {...}**

      renderComponent(mainElement, this._popup);
      console.log(this._popup);

**//log: Popup {_element: section.film-details, _card {...}**

      this._popup
        .getElement()
        .querySelector(".film-details__close-btn")
        .addEventListener("click", function () {
          console.log(this._popup);

**//log: undefined**

        });
    });
}

All this worked before I've tried to use a controller (I am studying OOP, so it goes...) Please, help. I've already spent about 5 hours on this line code and i have no idea what am i doing

  • 1
    `this` inside a callback defined with `function(){ ... }` is not the same `this` that is outside. – phuzi Nov 04 '20 at 13:22
  • "I've already spent about 5 hours on this line code and i have no idea what am i doing" ok, so here's a start: *never* write an attempted solution out in its entirety (here you have ~50 LoC!) without running it and hoping that it works. *Do* break a task into subtasks and do the first one using the simplest thing that could possibly work. Can I make something appear on the screen? Great. Can I make button? Great. Can I make the first thing e.g. disappear and re-appear when I click the button? Great. Can I make the first thing look like a window? Now you basically have a modal popup. – Jared Smith Nov 04 '20 at 13:22
  • 1
    @JaredSmith This was my first ever question asked on the internet and I know almost nothing about the context, that's why I decided to start from Adam and Eve. And the issue was that it perfectly worked (and obv. was organized somehow different) before i took this task with a controller, to make main.js not so piled with code. Thank you for advice and explanations, it is great to have such people here – Stan_Effy Nov 04 '20 at 13:41

2 Answers2

2

Try with this

  this._popup
    .getElement()
    .querySelector(".film-details__close-btn")
    .addEventListener("click", () => {
      console.log(this._popup);

    });

or

var self = this;
this._popup
    .getElement()
    .querySelector(".film-details__close-btn")
    .addEventListener("click", function() {
      console.log(self._popup);

    });
  • It worked, thanks a lot. What exactly is going on there? We 'stored' higher scope of this? – Stan_Effy Nov 04 '20 at 13:20
  • 1
    @Stan_Effy no, arrow functions pick up there `this` context from the enclosing scope, but `function` functions define their own `this`. – Jared Smith Nov 04 '20 at 13:24
  • See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#this_and_Arrow_Functions – 3limin4t0r Nov 04 '20 at 13:41
0

You have to pass the arrow function as the second argument of .addEventListener method because it has no own context and takes the parent context.

 this._popup
    .getElement()
    .querySelector(".film-details__close-btn")
    .addEventListener("click", () => {
      console.log(this._popup);
    });

Here you can read more about a function's this keyword.

Maksym Bezruchko
  • 1,223
  • 6
  • 23