Как получить данные веб-сокета в наблюдаемую и отобразить с помощью ngfor - PullRequest
0 голосов
/ 12 июня 2019

Я получаю данные из binso websocket и пытаюсь отобразить его свойства в таблице с помощью ngfor, но на консоли выдается ошибка «Cannot read property 'dispose of null'». Что мне нужно изменить?

Я пытался получить только одну строку данных без использования ngfor, и это было успешно. Но мне нужно получить более одного значения в таблице.

Вот мой сервис сокетов:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as socketIo from 'socket.io-client';
import * as Rx from 'rxjs/Rx';

@Injectable({
  providedIn: 'root'
})
export class SocketService {
  constructor(private http: HttpClient) { }

  private subject: Rx.Subject<MessageEvent>;

  public connect(url): Rx.Subject<MessageEvent> {
    if (!this.subject) {
      this.subject = this.create(url);
      console.log('Successfully connected: ' + url);
    }
    return this.subject;
  }

  private create(url): Rx.Subject<MessageEvent> {
    let ws = new WebSocket(url);

    let observable = Rx.Observable.create((obs: Rx.Observer<MessageEvent>) => {
      ws.onmessage = obs.next.bind(obs);
      ws.onerror = obs.error.bind(obs);
      ws.onclose = obs.complete.bind(obs);
      return ws.close.bind(ws);
    });
    let observer = {
      next: (data: Object) => {
        if (ws.readyState === WebSocket.OPEN) {
          ws.send(JSON.stringify(data));
        }
      }
    };
    return Rx.Subject.create(observer, observable);
  }
}

Вот мой сервис сообщений

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { SocketService } from './socket.service';

const CHAT_URL = 'wss://stream.binance.com:9443/ws/ethbtc@ticker';

export interface Message {
  sym: string;
  prch: string;
  prchp: string;
  lastp: string;


}


@Injectable({
  providedIn: 'root'
})


export class MsgService {
  public messages: Subject<Message>;

constructor(wsService: SocketService) {  this.messages = wsService.connect(CHAT_URL).map(
  (response: MessageEvent): Message => {
    const data = JSON.parse(response.data);
    return {
      sym: data.s,
      lastp: data.c,
      prch: data.p,
      prchp: data.P
    };
    }
) as Subject<Message>;

}
sendMsg(msg) {
  this.messages.next(msg);
}

}

Вот мой компонент

import { Component, OnInit } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs';
import { ApiService } from '../api.service';
import { Router } from '@angular/router';
import { MsgService, Message } from '../msg.service';

@Component({
  selector: 'app-main',
  templateUrl: './main.component.html',
  styleUrls: ['./main.component.css']
})
export class MainComponent implements OnInit {

  public values: Message;

  constructor(private apiservice: ApiService,private router: Router,private msgService: MsgService) { }

  ngOnInit() {


    this.msgService.messages.subscribe(data => this.values = data);

  }

onSelect(value){
this.router.navigate(['/detailed', value.symbol]);
}

}

И это HTML

<div class="container">


<h1 style="margin-left: 40%">
  Currencies
</h1>

<table class="table table-bordered table-info ">
  <thead>
    <tr>
      <th>Currency</th>
      <th>Last Price</th>
      <th>24h Volume</th>
      <th>24h Pct Change</th>

    </tr>
  </thead>
  <tbody>
    <tr (click)="onSelect(value)" *ngFor="let value of values | async">
      <td><a [routerLink]="['/detailed']"> {{value.sym}} </a></td>
      <td>{{value.prch}}</td>
      <td>{{value.prchp}}</td>
      <td>{{value.lastp}}</td>
    </tr>

  </tbody>
</table>

</div>

Я ожидаю, что HTML-таблица будет заполнена данными, поступающими из websocket. Вместо этого я получаю это на консоли:

 ERROR TypeError: Cannot read property 'dispose' of null
    at AsyncPipe.push../node_modules/@angular/common/fesm5/common.js.AsyncPipe._dispose (common.js:4937)
    at AsyncPipe.push../node_modules/@angular/common/fesm5/common.js.AsyncPipe.transform (common.js:4912)
    at Object.eval [as updateDirectives] (MainComponent.html:19)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:23911)
    at checkAndUpdateView (core.js:23307)
    at callViewAction (core.js:23548)
    at execComponentViewsAction (core.js:23490)
    at checkAndUpdateView (core.js:23313)
    at callViewAction (core.js:23548)
    at execEmbeddedViewsAction (core.js:23511)
...