Search code examples
angularrxjsobservablebehaviorsubjectsubject-observer

Angular RXJS Observables or Subjects passing numbers Internally


what's the correct RXJS approach to passing numbers within an Angular 5 app (no API)?

I've successfully passed a boolean with Subject :

service :

import {Injectable} from '@angular/core';
import {Subject} from 'rxjs/Subject';

@Injectable()
export class IsOpened {

  data = new Subject();

  constructor() {}

  insertData(data){
    this.data.next(data);
  }
}

emitter :

toggle(){
    this.opening = !this.opening;
    this._isOpened.insertData(this.opening);
}

listener :

ngAfterViewInit() {
    this._isOpened.data.subscribe((value) => {
      if(value) this.opened = true;
      else this.opened = false;
    }});
}

I sorta cheat in the listener because I don't store the received value but rather assess that and re-create the boolean.

works for me and fits in very few lines.

I can't do the same with numbers.

enter image description here

how would I do it with numbers? with arrays?

Google and the many RXJS info sources yielded nothing.


Solution

  • Here is an example of how to use Subject/BehaviorSubject with an object. This same technique would work for numbers.

    Service

    export class ProductService {
        private products: IProduct[];
    
        // Private to encapsulate it and prevent any other code from
        // calling .next directly
        private selectedProductSource = new BehaviorSubject<IProduct | null>(null);
    
        // Publicly expose the read-only observable portion of the subject
        selectedProductChanges$ = this.selectedProductSource.asObservable();
    
        changeSelectedProduct(selectedProduct: IProduct | null): void {
            this.selectedProductSource.next(selectedProduct);
        }
    }
    

    Component setting the value

      onSelected(product: IProduct): void {
        this.productService.changeSelectedProduct(product);
      }
    

    In this case, when the user picks something in one component, the selection is broadcast to several others.

    Component reading the value

    ngOnInit() {
        this.productService.selectedProductChanges$.subscribe(
            selectedProduct => this.product = selectedProduct
        );
    }
    

    In this example, the component reading the value stores it into its own local variable. That variable is used for binding and the UI changes based on the selected product.

    NOTE: You can achieve this SAME functionality using getters/setters with NO subject/behavior subject.

    I have a complete example using Subject/BehaviorSubject here: https://github.com/DeborahK/Angular-Communication/tree/master/APM-Final

    And the exact same functionality with getters/setters instead of Subject/BehaviorSubject here: https://github.com/DeborahK/Angular-Communication/tree/master/APM-FinalWithGetters