Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript ES6 calling a method inside another method within the same class shows an error the class i am calling is undefined [duplicate]

I am using Javascript ES6 classes. I have created a Player class as below:

class Player {

  constructor() {
     .....
     .....
  }
  changeShipDirection(shipName, direction) {
    let redraw = false;
    this.ships.filter(function(ship) {
        if (ship.name === shipName) {
            ship.direction = direction;
            if (ship.location.length > 0) {
                redraw = true;
                let coordinates = this.getCoordinatesOfShip(ship.name);
            }
        }
     });

     return redraw
   }

   getCoordinatesOfShip(shipName) {
      let coordinates = [];
      this.ships.filter(function(ship) {
          if (ship.name === shipName) {
              coordinates = ship.location;
          }
      });

      return coordinates;
   }

}

I get the following error:

Cannot read property 'getCoordinatesOfShip' of undefined

I have cases where I use the same technique i.e. calling a method within the class and it works.

like image 563
ka222jm Avatar asked Nov 26 '25 03:11

ka222jm


1 Answers

That's because this inside that function you passed to filter is not bound to the class. There are multiple ways to fix it.

One is to use arrow function which retains the this binding of the scope it's defined in

this.ships.filter((ship) => {
        if (ship.name === shipName) {
            ship.direction = direction;
            if (ship.location.length > 0) {
                redraw = true;
                let coordinates = this.getCoordinatesOfShip(ship.name);
            }
        }
     });

Another can be to first retain the this reference for the outer function in some other variable and then use that inside the function passed to filter -

var self = this
this.ships.filter(function(ship) {
        if (ship.name === shipName) {
            ship.direction = direction;
            if (ship.location.length > 0) {
                redraw = true;
                let coordinates = self.getCoordinatesOfShip(ship.name);
            }
        }
     });

Yet another way is to bind that function to the this bound to the outer function -

this.ships.filter(function(ship) {
        if (ship.name === shipName) {
            ship.direction = direction;
            if (ship.location.length > 0) {
                redraw = true;
                let coordinates = this.getCoordinatesOfShip(ship.name);
            }
        }
     }.bind(this));
like image 182
Mukesh Soni Avatar answered Nov 28 '25 17:11

Mukesh Soni



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!