Womprat
Womprat

Reputation: 153

How do I turn an array into an Observable in Angular 10?

I'm doing a simple display of data from a Gemini bitcoin websocket. I am able to subscribe to the websocket and process the incoming messages in my subscribe function. This all works as expected. dataFromMessages changes values as I process new messages.

What is the next step to make dataFromMessages an Observable?

I know if it's an Observable, then I can use "| async" in my html. Or I can subscribe to the Observable. But I don't know how to make it an Observable. Use the or() function?

output.component.ts

import { Component, OnInit } from '@angular/core';
import { UserWebsocketService } from '../services/user-websocket.service';

export class OutputComponent implements OnInit{

  dataFromMessages;

  constructor(private websocket: UserWebsocketService){}

  ngOnInit(): void {
    this.websocket.connect('wss://api.gemini.com/v1/marketdata/btcusd')
    .subscribe(message => this.process_message(message));
  }

  process_message(message){
    // *** do processing here with incoming message object***
    
    this.dataFromMessages = processed_data;
  }
}

output.component.html

<table>
  <thead>
    <tr> <th>Bid</th> <th>Ask</th> </tr>
  </thead>
  <tbody>
    <tr *ngFor="let item of dataFromMessages">
      <td>{{ item.bid }}</td>
      <td>{{ item.ask }}</td>
    </tr>
  </tbody>
</table>

Upvotes: 1

Views: 1341

Answers (2)

Bertramp
Bertramp

Reputation: 385

You should declare your dataFromMessages as an observable of the type you want. Then in ngOnInit() use the rxjs map() operator inside a pipe to do your processing and return it. In here you can use the message "normally" and after the pipe finishes it will be an observable transformed with the operators you used inside the pipe.

Then in your HTML use the async pipe

<tr *ngFor="let item of dataFromMessages$ | async">
  <td>{{ item.bid }}</td>
  <td>{{ item.ask }}</td>
</tr>
dataFromMessages$: Observable<myDataType>;

ngOnInit(): void {
  dataFromMessages$ = this.websocket.connect('wss://api.gemini.com/v1/marketdata/btcusd').pipe(
    map(message => {

      // Do my quantum physics and message processing here

      return processed_data;
    })
  );
}

Upvotes: 0

Kamran Khatti
Kamran Khatti

Reputation: 4137

Initialize dataFromMessages as observable;

dataFromMessages$: Observable<any>;

Instead of subscribe you can use rxjs pipe and tap operators to do the magic

 ngOnInit(): void {
   this.dataFromMessages$ = this.websocket.connect('wss://api.gemini.com/v1/marketdata/btcusd')
   .pipe(tap(message) => this.process_message(message));
}

And in process_message method return the processed message.

process_message(message){
   // *** do processing here with incoming message object***

   return processed_data;
}

And in template use async pipe to subscribe and read data.

<tr *ngFor="let item of dataFromMessages$ | async">
  <td>{{ item.bid }}</td>
  <td>{{ item.ask }}</td>
</tr>

Upvotes: 2

Related Questions