0

I am losing 'this' context in the child class when using getJSON to retrieve some JSON when using a callback from the parent class. I solve this by doing self = this and then passing the self variable but it seems incorrect and not the correct way of achieving this.

I know the code is formatted incorrectly but I do not know how to fix it.

I have tried arrow functions but I still seem to not get the 'this' context.

class RadioPlayer extends Radio{ 

    constructor(xProvider) {
        super(xProvider);
    }

    retrieveStations(xStationsCallback) {
      this.xStationsCallback = xStationsCallback;
      let url = 'stations.json';
      this.getFromPoint(this.radioPlayerCallback, url);
    }

    //Self = this;
    radioPlayerCallback(xData, self){
      self.stations = xData;
      self.xStationsCallback();
    }
}
class Radio{
    constructor(xProvider) {
        // if (new.target === TwineRadio) {
        //   throw new TypeError("Cannot construct TwineRadio instances directly");
        // }
        this.provider = xProvider;
        this.stations = null;
    }

    getFromPoint(xRadioPlayerCallback, url){
      //Ensure reference to this is passed to the child as it loses focus
      let self = this;
      $.getJSON(
      url, function(data){
        xRadioPlayerCallback(data, self);
      });
    }

    getStations(){
        return this.stations;
    }

    getProvider(){
        return this.provider;
    }
}

<!DOCTYPE html>
<html>
<head>
    <title>Radio API prototype</title>
    <script src="Radio.js"></script>
    <script src="RadioPlayer.js"></script>
    <script
        src="https://code.jquery.com/jquery-3.4.1.min.js"
        integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
        crossorigin="anonymous">
    </script>
</head>
<body>
<script>
function StationsCallback(){
    console.log(RadioPlayer.stations);
}

RadioPlayer = new RadioPlayer("RadioPlayer");
RadioPlayer.retrieveStations(StationsCallback);
</script>
</body>
</html>

The code provided works by creating a new variable that referencing self and then passing it to the callback function but then I have to use the self variable instead of this which seems difficult to manage. The classes are in different files.

1 Answers1

0

Use arrow function:

    getFromPoint(xRadioPlayerCallback, url){
      $.getJSON(
      url, (data) => {
        xRadioPlayerCallback(data, this);
      });
    }

Arrow functions receive this from closure, when function() {} - from context of calling.

  • Thank you, how in my callback do I access this as its still not accessible. radioPlayerCallback(xData){ this.stations = xData; this.xStationsCallback(); } I receive the error: Cannot set property 'stations' of undefined – user3676601 Aug 04 '19 at 19:52