Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript - retain scope in event listener

I am converting my AS3 codebase to TypeScript and run into this error:

AS3 code:

private function loadDataXml(assetsXml : String) : void {
    var loader : URLLoader = new URLLoader();
    loader.addEventListener(Event.COMPLETE, handleDataLoaded);
    loader.load(new URLRequest(assetsXml));
}

private function handleDataLoaded(event : Event) : void {
    var xml_data : XML = new XML(event.target.data);
    parseData(xml_data);
    .........
}

private function parseData(xml_data : XML) : void {
    ......
}

TypeScript code

private loadDataXml(assetsXml : string) {
    var xmlRequest:XMLHttpRequest = new XMLHttpRequest();
    xmlRequest.addEventListener("load",this.handleDataLoaded, false);
    xmlRequest.open("GET", assetsXml, false);
    xmlRequest.setRequestHeader("Content-Type", "text/xml");
    xmlRequest.send(null);
}

private handleDataLoaded(evt:Event) {
    var xmlDoc:Document = (<XMLHttpRequest> evt.target).responseXML;
    this.parseXMLData(xmlDoc);
    ......
}

private parseData(xmlDoc:Document):void {
    ......
}

and I get this error "Uncaught TypeError: Object # has no method 'parseData'" because of this line xmlRequest.addEventListener.....

I have tried using arrow function but still couldn't fix it (and i don't think I use it correctly)

like image 456
user2694951 Avatar asked Aug 24 '13 21:08

user2694951


1 Answers

When you need to pass functions around use the new lambda syntax for member variables (introduced in TypeScript 0.9.1):

private loadDataXml(assetsXml : string) {
    var xmlRequest:XMLHttpRequest = new XMLHttpRequest();
    // you are passing a member function Use lambda to define this function: 
    xmlRequest.addEventListener("load",this.handleDataLoaded, false);
    xmlRequest.open("GET", assetsXml, false);
    xmlRequest.setRequestHeader("Content-Type", "text/xml");
    xmlRequest.send(null);
}

private handleDataLoaded = (evt:Event) => { // Since you want to pass this around  
    var xmlDoc:Document = (<XMLHttpRequest> evt.target).responseXML;
    this.parseXMLData(xmlDoc);  // you will get the correct this here 
    ......
}

private parseData(xmlDoc:Document):void {
    ......
}
like image 114
basarat Avatar answered Sep 30 '22 15:09

basarat