Daniel Stafford Daniel Stafford - 16 days ago 5
TypeScript Question

WebSocket callback within arrow function not setting 'this' lexically

I am trying to create a WebSocket service in Angular 2. Here is what I have so far:

import {Injectable} from "angular2/core"
@Injectable()
export class ServerService {

public ws:WebSocket;

public myData = {};

constructor() {
let ws = new WebSocket('ws://localhost:8080/');

ws.onopen = (event:Event) => {
console.log("Socket has been opened!");
};

ws.onmessage = (event:Event) => {
this.myData = JSON.parse(event.data);
};
};
}


The problem is, when
onmessage
runs, the
this
keyword becomes the WebSocket object, instead of my
ServerService
object.

It seems like my arrow function is acting as a standard function. What could be causing this? Is there another way to get back to the
ServerService
object?

Answer

OK, so after seeing Abdulrahmans example working in plunk, I figured there was probably something wrong with my environment. Turns out my TypeScript was compiling to ES5, and was outputting:

function ServerService() {
                var _this = this;
                this.myData = {};
                var ws = new WebSocket('ws://localhost:8080');
                ws.onopen = function (event) {
                    console.log("Socket has been opened!");
                };
                ws.onmessage = function (event) {
                    _this.myData = JSON.parse(event.data);
                };
            }

My arrow functions were indeed being removed, but replaced with something that should(?) be functionally equivalent. It works as expected in Firefox, but not in Chrome (which is where I was debugging).

I switched my TypeScript compiler to output ES6, and now I have arrow functions in my JavaScript, and my code works as expected in both browsers.

Comments