socket.io客户端Angular无法读取未定义的属性'emit'

时间:2020-02-15 01:02:57

标签: angular socket.io

我在Angular中拥有这个组件

import { Component, OnInit} from "@angular/core";
import * as io from "socket.io-client";
import { environment } from "src/environments/environment";

@Component({
  selector: "app-home",
  templateUrl: "./home.component.html",
  styleUrls: ["./home.component.css"]
})
export class HomeComponent implements OnInit {
  busy: boolean;
  username: string;
  socket: any;
  user = JSON.parse(localStorage.getItem("user"));
  token = localStorage.getItem("token");

  constructor() {
    // THIS WORKS
    this.socket = io.connect(environment.endpoint, {
      query: `username=${this.user.username}&token=${this.token}`
    });
  }

  ngOnInit() {
    this.socket.on("client-retrieve", function(data) { // <--- THIS WORKS
      console.log(data);
      this.socket.emit( // <---------- THIS FAILS, throws the error
        "request-response",
        {
          from: this.user.username,
          to: data.from,
          command: "SEND",
          payload: [{ 'something': "something" }]
        },
        (err, message) => {
          console.log(err);
          console.log(message);
        }
      );
    });
  }

  onSubmit(formData) {
    console.log("FormData: ", formData);
    this.socket.emit( // This works. Gets triggered by a form submit
      "request-forward",
      {
        command: "PULL",
        from: this.user.username,
        to: formData.username
      },
      (err, message) => {
        console.log(err);
        console.log(message);
      }
    );
  }
}

抛出的错误基本上是: core.js:5828 ERROR TypeError: Cannot read property 'emit' of undefined. at Socket.<anonymous> (home.component.ts:26)

我在做什么错?因为通过onSubmit(...)进行调用可以工作。

1 个答案:

答案 0 :(得分:1)

您需要将其更改为箭头功能,以便将引用词法上下文而不是调用者上下文。

在这一行:

this.socket.on("client-retrieve", function(data) { // <--- THIS WORKS

更改为此:

 this.socket.on("client-retrieve", (data) => { // <--- THIS WORKS

您的方法现在应如下所示:

  ngOnInit() {
    this.socket.on("client-retrieve", (data) => { // <--- THIS WORKS
      console.log(data);
      this.socket.emit( // <---------- THIS FAILS, throws the error
        "request-response",
        {
          from: this.user.username,
          to: data.from,
          command: "SEND",
          payload: [{ 'something': "something" }]
        },
        (err, message) => {
          console.log(err);
          console.log(message);
        }
      );
    });
  }

https://www.typescriptlang.org/docs/handbook/functions.html#this-and-arrow-functions