Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

TypeError: Cannot read properties of undefined (reading '_matrix')

I want to write my position of figures on chess board (checkers) from Node List of tiles. I define a 2-dimensional array and fill it with 0. And I can freely change the value, if I use this._matrix[0][1] = 1; right at the start of method. However, when it comes to changing it inside of a forEach array, I get this type of error.

how it is supposed to finally be

My code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

class Game{
    _matrix = Array(8).fill().map(() => Array(8).fill(0));
    _board = document.querySelectorAll("div.container>div"); // all tiles

    constructor(blackTiles){
        this.blackTiles = blackTiles;
    }
    
    fillMatrix(){
        console.log(this._matrix[0][1]) // 0
        this._matrix[0][1] = 1 // no errors
        console.log(this._matrix[0][1]) // 1

        this._board.forEach(function(element, i){
            if(i < 8){
                if(element.classList.contains("infest")){ //tiles, that have figures, have class "infest"
                    try{
                        let row = i / 8;
                        let col = i % 8;
                        this._matrix[parseInt(row)][parseInt(col)] = 1; //error
                    } catch(Error) { console.error(Error); }
                }
                i++;
            }
        });

        return this._matrix;
    }
}

Full error:

TypeError: Cannot read properties of undefined (reading '_matrix')
    at script.js:41:30
    at NodeList.forEach (<anonymous>)
    at Game.fillMatrix (script.js:35:21)
    at window.onload (script.js:102:22)

>Solution :

As you correctly found, the problem is on that specific line.

That is because inside a function, (defined with function(){}), this refers to the function itself, not the containing context.

You have three options at this point.

  1. Make and use a reference to this (old school :)):
const _this = this;
list.forEach(function(){
    _this.something;
})
  1. Bind the function to the current object:
list.forEach((function(){
    this.something;
}).bind(this));
  1. Use an arrow function; it will be bound to the caller automatically:
list.forEach(() => {
    this.something;
});
  1. Bonus point: if you are using classes, you could also have a private lambda property do that as well:
_handleSomething = () => {
    this.something;
}

list.forEach(this._handleSomething);

I’d go for option 3.

Option 4 is useful when your function is an event handler that you need to remove afterwards.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading