Angular 6 BehaviorSubject'未定义':错误:TypeError:无法读取声明的BehaviorSubject的属性

时间:2018-08-16 18:00:58

标签: angular rxjs spring-websocket behaviorsubject

我对Angular(以及StackOverflow)还很陌生,我一直在尝试使用Spring Boot作为后端和WebSockets来制作一个小项目,以尝试制作一个小型的实时Web应用程序(所有这些技术对我来说还很新,我很想学习它们!)。我遇到的问题是使用BehaviorSubjects。每当通过WebSocket从Spring Boot收到消息时,我打算使用BehaviorSubject('messageSubject $')。基本上,一旦我收到一条消息,我就可以使用'next()'方法让BehaviorSubject接起来,然后让我的一个组件订阅它(对Web套接字的订阅和对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();
  }

很抱歉,以前是否曾提出过这样的问题,我在这里对我的问题进行了很多研究,但是解决方案建议的所有更改似乎都没有奏效。非常感谢您的帮助,如果需要更多代码段或信息,我很乐意为您提供这些代码段!

1 个答案:

答案 0 :(得分:0)

问题将由您的回调中“ this”的范围不同引起。 JavaScript具有“ this”的概念,与大多数其他语言不同,但是typescript(和现代Javascript)具有另一种语法可以解决此问题,从而使您更直观地了解“ this”。

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

.. and ...

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);
        }
    });
});