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?
b) Arrow Function These were introduced in ES6. Their concise syntax and handling of the this keyword has made JavaScript arrow functions an ES6 favourite among developers. If there are no parameters, then you can place empty parentheses before => like the below example.
As you can see, (a, b) => a + b means a function that accepts two arguments named a and b . Upon the execution, it evaluates the expression a + b and returns the result. If we have only one argument, then parentheses around parameters can be omitted, making that even shorter.
Arrow function is one of the features introduced in the ES6 version of JavaScript. It allows you to create functions in a cleaner way compared to regular functions. For example, This function // function expression let x = function(x, y) { return x * y; }
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.
I fixed it using Function.prototype.bind(), which is only available on oldschool anonymous functions, not arrow functions.
So instead of:
ws.onmessage = (event:Event) => {
this.myData = JSON.parse(event.data);
};
I did:
ws.onmessage = function(event:Event) {
this.myData = JSON.parse(event.data);
}.bind(this);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With