Archiv für den Monat Oktober 2015

TypeScript “this.propertyname” ist “undefined” in Lambda Funktionen beim Debgging mit VS


Seit dem ich TypeScript kenne, möchte ich es nicht mehr missen, nur leider gibt es beim Debuggen von Lambda Funktionen direkt im Visual Studio ein Problem beim Verwenden von “this”. Man muss zwar selbst keine lokale Variable “self” oder “that” anlegen der man “this” zuweist, damit man in Lambda Funktionen auf den Ursprungskontext zugreifen kann, aber wenn man dann im Debugmodus ist und die jeweilige Variable debuggen möchte steht bei “this.propertyName” immer “undefined”.

Obwohl wir die Variable entsprechend gebunden wurde und auch zugewiesen wurde, ist sie weiterhin “undefined” für den Debugger.

image

Dabei handelt es sich “nur” um ein Tooling Problem vom VS, denn TypeScript übernimmt in den Lambda Funktionen automatisch das Erstellen einer “self” Variable mit dem namen “_this”. Der Code für die init Funktion in JavaScript sieht dann folgendermaßen aus:

 TodoEditModalCtrl.prototype.init = function () {
     var _this = this;
     this.todoSrv.loadTodoItem(this.todoId).then(function (result) {
         //Unser Datum noch in ein richtiges Datum verwandeln
         result.DoDate = moment(result.DoDate).toDate();
         _this.viewModel = result;
     });
 };

und leider erkennt der aktuelle VS Debugger nicht das es sich bei dem “this” in der Lambda Funktion um “_this” handelt.

Daher verwende ich in VS das Watch Fenster und füge dort selbst “_this” oder “_this.propertyName” zur Watch hinzu. Das ist zwar nicht ganz so komfortabel wie direkt mit der Maus über die Variable, aber ich muss dafür auch nicht extra wieder eine “self” Variable anlegen und kann weiterhin “this” in Lambda Ausdrücken verwenden.

image

Damit ist es zumindest in VS möglich das “this.proertyName” wieder entsprechend zu debuggen.

Advertisements

TypeScript und einige “neue” ES5/6 Array und String Funktionen


Seit dem ich TypeScript in meinen Projekten verwende, kann ich auch auf die neuesten JavaScript Funktionen von ES5/6 für Strings oder Arrays zugreifen. Denn eines der größten Mankos vom “alten”  JavaScript (<ES5) ist der Zugriff auf Arrays, ich kann mich noch gut an die Tage erinnern in denen ich die gute alte for Schleife und einen Index verwendet habe um dann bestimmte Elemente zu finden, oder zu prüfen ob ein Element mit dem Namen enthalten ist. Hier wurde zum Glück nachgebessert und kann in TypeScript nativ verwendet werden und nicht nur bei den Array Funktionen gibt es Fortschritte, sondern auch beim Verketten von Strings.

1. String Funktion: Verketten von Strings über mehrere Zeilen

Wenn man früher einen langen String hatte den man verketten wollten, dann war dies nur über “+” Zeichen möglich.

var oldStringadd = "In EcmaScript 6 werden endlich Multiline Strings" +
        "unterstüzt ohne das man immer ein lästiges" +
        "Plus Zeichen verwenden muss. Da" +
        "TypeScript auch ES6 Nutzt kann man hier" +
        "auf die gleichen Features zugreifen.";

Aber mit TypeScript kann man dies jetzt folgendermaßen darstellen, ohne lästige zusätzliche Anführungszeichen und “+” Zeichen.

 //Mehrzeiliger String ohne "+" Verkettung mit "back-tick" bzw. grave accent Zeichen.
 return `In EcmaScript 6 werden endlich Multiline Strings
              unterstüzt ohne das man immer ein läastiges
              Plus Zeichen verwenden muss. Da 
              TypeScript auch ES6 Nutzt kann man hier 
               auf die gleichen Features zugreifen.`;

2. String Funktion: String Format

Das Zusammenstückeln von Strings mit Hilfe von “+” Zeichen und Variablen die man einsetzen möchte funktioniert zwar schon seit Jahren.

   var items = [];
         items.push("Auto");
         items.push("Fahrrad");
         items.push("Moped");

  var oldStringFormat = "Wir haben " + items.length + " Fahrzeugtypen bei uns Zuhause dazu gehört auch ein " +  items[0] + ".";

aber es gibt endlich auch eine elegantere Methode mit “${VarName}” direkt im String. Auch hier muss wie beim Verketten von Strings der “grave-accent”  “ ` ” verwendet werden.

//String Format mit ES6
return `Wir haben ${items.length} Fahrzeugtypen bei uns Zuhause dazu gehört auch ein ${items[0]}.`;

Demodaten für die Array Funktionen:

class Person {
      constructor(public name: string, public age: number) {  }
}

//Liste der Personen erstellen
this.personList = [];
this.personList.push(new Person("Maiks", 12));
this.personList.push(new Person("Hannes", 17));
this.personList.push(new Person("Thomas", 23));
this.personList.push(new Person("Ilsche", 6));
this.personList.push(new Person("Sreddy", 27));
this.personList.push(new Person("Henries", 11));

3. Array Funktion: every

Prüfen ob in einem Array alle Einträge mit der übergebenen Bedingung übereinstimmen und nur dann wird ein True zurückgegeben

//Ergebnis: False - Prüft ob alle Einträge größer 12 sind und nur dann wird True zurückgegeben
var alleAelter12 = this.personList.every((element, index, array) =&gt; {
        return element.age &gt; 12;
});
//Ergebnis: True - Denn alle Namen enthalten ein "S"
var entaeltBuchstabeS = this.personList.every((element, index, array) =&gt; {
    //Wenn der Buchstabe "S" im String gefunden wird, wird ein Index größer -1 zurückgegeben!
    return element.name.toLowerCase().indexOf("s") &gt; -1;
});

4. Array Funktion: some

Prüft ob nur eines der Listenelemente der Bedingung entspricht und gibt dann bereits True zurück.

//Ergebnis: True - Prüft ob mindestens ein Eintrag dem Kriterium entspricht und gibt dann True zurück
var mindestensEinerJuengerAls12 = this.personList.some((element, index, array) =&gt; {
    return element.age &lt; 12;
});

5. Array Funktion: filter

Gibt eine Liste mit den Einträgen zurück die den Filterkriterien entsprochen haben.

//Gibt eine Neue Liste mit den gefilterten Einträgen zurück
var alleAelter18: Person[] = this.personList.filter((element, index, array) =&gt; {
    if (element.age &gt; 18) {
        return true;
    }
});

6. Array Funktion: forEach

Eine einfache Methode ein Array Element für Element durchzugehen, diese Methode hat selbst keinen Rückgabewert.

var meinePersonen: Person[] = [];
//For Each Schleife - hat keinen Rückgabewert
this.personList.forEach((element, index, array) =&gt; {
    if (element.age &gt; 10 &amp;&amp; element.age &lt; 20) {
        meinePersonen.push(element);
    }
});

7. Array Funktion: sort

Sortiert das aktuelle Array z.B. nach einer Zahl oder einem String

//Sortieren der Array Einträge nach dem Alter mit Sort.
this.personList.sort((person1, person2) =&gt; {
   return person1.age - person2.age;
});

//Sortieren der Array Einträge nach dem Namen
this.personList.sort((person1, person2) =&gt; {
    return  person1.name.localeCompare(person2.name);
});

Hinweis Array Funktionen

Bei den meisten Array Funktionen wurde eine Anonyme Methode verwenden mit drei Parametern:

  • element: Immer das aktuelle Element für den jeweiligen Durchlauf der anonymen Methode
  • index: der katuelle Index im Array für das aktuelle Element im Durchlauf
  • array: das komplette Array selbst

Hier müssen natürlich nicht immer aller Properties übergeben werden, meist reicht auch nur das element selbst aus.

//Alle Aufrufe sind AUCH nur mit einem oder zwei Parametern möglich.
var alleAelter5 = this.personList.every((element) =&gt; {
    return element.age &gt; 5;
});

Wer noch weitere Coole Funktionen Kennt die ich vergessen haben sollte kann dies gerne in den Kommentaren ergänzen.