【问题标题】:socket.io client Angular Cannot read property 'emit' of undefinedsocket.io客户端Angular无法读取未定义的属性“发射”
【发布时间】:2020-02-15 01:02:57
【问题描述】:

我在 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.&lt;anonymous&gt; (home.component.ts:26)

我做错了什么?因为通过 onSubmit(...) 调用 emit 有效。

【问题讨论】:

    标签: angular socket.io


    【解决方案1】:

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

    在这一行:

    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

    【讨论】:

    • 箭头函数的哪一部分?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 2020-09-22
    相关资源
    最近更新 更多