1

I'm trying to learn typescript. In this attempt, I am trying to get an array of numbers, from a webservice I have created, into a javascript array.

I have the following Typescript class:

class GameMap2 {
    Grid: Uint8Array;
    width: number;
    height: number;

    constructor(height: number, width: number) {
        this.height = height;
        this.width = width;
        this.Grid = new Uint8Array(height * width);
    }

    generateMap() {
        alert("calling generate");
        $.ajax({
            url: "/api/Maps/" + this.width + "/" + this.height,
            async: false,
            dataType: 'json',
            success: function(data) {
                alert("Ajax success");
                for (var idx = 0; idx < data.length; idx++) {
                    this.Grid[idx] = data[idx];
                }
            }
        });

    }
}

From the webservice, I will get something like: [1,1,1,1,1,1,1,1,1,0,0,0,1,0,0,1,1,1,1,0,1,0,1,1,1,0,0,0,1,0,0,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1] Now, when I try to loop through this result, and put it into the Grid array, I get the error: TypeError: Cannot set property '0' of undefined

If I change it to This.Grid.Push(data[idx]); I get undefined errors. It seems to me, that my Grid array is not actually within reach of my ajax callback. Can that really be true, or am I doing something wrong here? Is there another way I can get my array into the javascript array?

Nicolai
  • 2,835
  • 7
  • 42
  • 52

2 Answers2

2

Well in fact, this issue is solved directly by TypeScript. The feature is called arrow function and would change your code defintion like this

class GameMap2 { 
    ...
    constructor(height: number, width: number) { ... }

    generateMap() {
        alert("calling generate");
        $.ajax({

            // instead of this
            // success: function(data) {
            // use this style, and the compiler will do the magic
            // of keeping correct "this" for us
            success: (data) => {
                alert("Ajax success");
                for (var idx = 0; idx < data.length; idx++) {
                    this.Grid[idx] = data[idx];
                }
            }
         ....

See TypeScript Arrow Function Tutorial (small cite)

... “Arrow function expressions are a compact form of function expressions that omit the function keyword and have lexical scoping of this.” Basically the Arrow Function helps you retain a certain scope automatically. If you look at the outputted code from the compiler, it just creates a var _this = this; and it is used inside the function.

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
1

It's because this has changed context in the success callback. Make a reference to this and use that instead:

generateMap() {
  alert("calling generate");
  var _this = this;
  $.ajax({
    url: "/api/Maps/" + this.width + "/" + this.height,
    async: false,
    dataType: 'json',
    success: function(data) {
      alert("Ajax success");
      for (var idx = 0; idx < data.length; idx++) {
        _this.Grid[idx] = data[idx];
      }
    }
  });
}
Andy
  • 61,948
  • 13
  • 68
  • 95
  • 1
    It's the `this` and `that` convention. The following question: http://stackoverflow.com/questions/4886632/what-does-var-that-this-mean-in-javascript shows why and how to use it. – djikay Jun 24 '14 at 15:58
  • I use `_this` because that's the code convention I've chosen. – Andy Jun 24 '14 at 15:59