Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update subscribers of Angular Observable

In my angular app, I have created an Observable to provide data updates to multiple components. When user clicks on a button, all the Subscribers of the Observable should be updated with different set of data. Below is the code.

import { Observable } from 'rxjs/Observable';
import { Subscriber } from 'rxjs/Subscriber';

export class MyService {
private data: number[] = [5,6,7,8];

/// The observable given to outside
private observable: Observable<number[]>;

/// Subscribers of the observable which is given to outside
private subscribers: Map<number, Subscriber<number[]>>;
private nextSubscriberId = 0;

constructor() {
    this.subscribers = new Map();
    this.observable = new Observable(subscriber => {
        const id = ++this.nextSubscriberId;
        this.subscribers.set(id, subscriber);

        subscriber.next(data);

        return () => { this.subscribers.delete(id); };
    });

}

}

At the button click event I do the following

data = [1,2,3,4]; 
this.subscribers.forEach((subscriber, key) => {
    subscriber.next(data);
    });

My question is, Is this the best way of managing subscribers of an Observable ? Are there any alternative ways of handling subscribers instead of managing them by our self ?

like image 642
dGayand Avatar asked Mar 29 '18 16:03

dGayand


Video Answer


1 Answers

You're basically tying to create your own implementation of Subject. Try this:

import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

export class MyService {
  private source = new Subject<number[]>();
  data$ = this.source.asObservable();

  constructor() {}

  next(data: number[]) {
    this.source.next(data);
  }
}

producer.component.ts

class ProducerComponent {
  constructor(private myService: MyService) {}

  ngOnInit() {
    this.myService.next([1,2,3]);
  }
}

consumer.component.ts

class ConsumerComponent {
  constructor(private myService: MyService) {}

  ngOnInit() {
    this.myService.data$.subscribe(data => // ...)
  }
}

If you want to have an initial value in your service, replace:

private source = new Subject<number[]>();

with

private source = new BehaviorSubject<number[]>([1,2,3,4]);, where [1,2,3,4] is the initial value.

like image 135
Tomasz Kula Avatar answered Oct 19 '22 21:10

Tomasz Kula