【问题标题】:Angular 6 BehaviorSubject 'undefined': Error: TypeError: Cannot read property of my declared BehaviorSubject [duplicate]Angular 6 BehaviorSubject“未定义”:错误:TypeError:无法读取我声明的 BehaviorSubject 的属性 [重复]
【发布时间】:2018-08-16 18:00:57
【问题描述】:

我对 Angular(以及 StackOverflow)还很陌生,我一直在尝试使用 Spring Boot 作为我的后端和 WebSockets 来制作一个小型项目,以尝试制作一个小型实时 Web 应用程序(所有这些技术对我来说相当新,我很想学习它们!)。我遇到的问题是使用 BehaviorSubjects。每次我通过 WebSocket 从 Spring Boot 收到消息时,我都打算使用我的 BehaviorSubject ('messageSubject$')。基本上,一旦我收到一条消息,我就会让我的 BehaviorSubject 使用“next()”方法接收它,然后让我的一个组件订阅它(订阅我的网络套接字和我的 BehaviorSubject 的定义都在服务)。但是,当我这样做时,我在 Google Chrome 的控制台上显示一个错误:'错误:TypeError:无法读取未定义的属性'messageSubject $'。我很困惑为什么会弹出这样的错误,因为我确实确保正确定义它(我看过多个教程,它们似乎都以相同的方式做)。

这是我从 rxjs 导入 BehaviorSubject 的方式:

import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';

这是 BehaviorSubject 定义(在构造函数之上):

private messageSubject$ = new BehaviorSubject<string>('default message');

这是对我的 WebSocket 的订阅以及我尝试使用我的行为主题的地方:

    // Connecting to WebSocket found in Spring Boot MS. Also checkout polyfill.ts
  connect(user: string, password: string) {
    console.log('Inside Connect. Guest and Password: ' + user + ' ' + password);
    const socket = new SockJs('http://localhost:8080/football-ws');
    this.stompClient = Stomp.over(socket);
    this.stompClient.connect(user, password, this.onConnected);
    console.log('Attempting to connect!');
  }

  onConnected = (frame: any) => {
    console.log('Frame: ' + frame);
    this.stompClient.subscribe('/topic/public', this.onMessageReceived);
  }


  onMessageReceived(message: any) {
    console.log('Message Received from MS: '  +  message);
    try {
      this.messageSubject$.next(message.body);
    } catch (e) {
      console.log('Error: ' + e);
    }
  }

  getMessageSubject() {
    return this.messageSubject$.asObservable();
  }

如果以前有人问过这样的问题,我深表歉意,我在这里对我的问题进行了很多研究,但是所建议的解决方案似乎都没有任何改变。非常感谢大家的帮助,如果需要更多的代码 sn-ps 或信息,我很乐意提供给您!

【问题讨论】:

  • 您正在查看代码的错误部分。 “无法读取未定义的属性 'messageSubject$'”意味着您的服务实例未定义,而不是 messageSubject$ 本身 - 您仍然没有应该包含 messageSubject$ 的类的实例。
  • 尝试用箭头函数定义onMessageReceived,就像定义onConnected:onMessageReceived = (message: any) =&gt; { ... }一样。
  • 哦,怎么会这样?我需要在 app.module.ts 中定义服务吗?我确实将它列为那里的提供者,但问题仍然存在。 @LazarLjubenović
  • 我认为这不是问题@LazarLjubenović - 这是关于“这个”范围的 - 请参阅我的答案。
  • @MarkHughes - 我个人不太使用bind 语法,但我已经习惯了,因为我每天都会多次将该问题标记为重复。 :-)

标签: angular rxjs spring-websocket behaviorsubject


【解决方案1】:

这个问题是由于你的回调中“this”的范围不同造成的。 JavaScript 有一个“this”的概念,这与大多数其他语言不同,但是 typescript(和现代 Javascript)有另一种语法来解决这个问题,给你一个更直观的“this”行为。

this.stompClient.connect(user, password, (frame: any) => this.onConnected(frame));

.. 和 ...

this.stompClient.subscribe('/topic/public', (message: any) => this.onMessageReceived(message));

此语法确保“this”的值与您在执行回调时所期望的一样。

您也可以使用这种语法将回调内联,例如:

this.stompClient.connect(user, password, (frame: any) => {
    console.log('Frame: ' + frame);
    this.stompClient.subscribe('/topic/public', (message: any) => {
        console.log('Message Received from MS: '  +  message);
        try {
            this.messageSubject$.next(message.body);
        } catch (e) {
            console.log('Error: ' + e);
        }
    });
});

【讨论】:

    猜你喜欢
    • 2022-01-13
    • 2018-12-13
    • 1970-01-01
    • 2018-10-26
    • 2019-04-28
    • 2018-12-18
    • 2019-02-06
    • 1970-01-01
    • 2021-03-18
    相关资源
    最近更新 更多