Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Components - Output encapsulating a BehaviorSubject

Tags:

angular

rxjs

I have a component with an internal state, stored in a RxJS BehaviorSubject (containing the size of a certain DOM element, by the way).

I would like to expose this state as an @Output() property.

The most naive implementation I can think of is this:

// inside myComponent

private _state$ = new BehaviorSubject<Something>(...);

@Output() stateChange = new EventEmitter<Something>();

constructor() {
  // skipping unsubscription for the sake of this simplistic example
  this._state$.subscribe(newState => this.stateChange.emit(newState);
}

However, this will NOT emit the currently stored value as a BehaviorSubject does as soon as there is a new subscription. Late subscribers are not going to get the current value.

Is there a simple approach for cases like this? I would like to expose the state and basically stop worrying about the order of the events, as I do with a simple BehaviorSubject<T>.

like image 925
A. Chiesa Avatar asked Aug 17 '26 17:08

A. Chiesa


1 Answers

EventEmitter in Angular is a simple extension of RxJS Subject. So theoretically we should be able to achieve your expected behavior by creating a custom emitter by extending BehaviorSubject instead of Subject. A crude implementation would be:

import { BehaviorSubject } from 'rxjs';
    
export class BehaviorEventEmitter<T extends any> extends BehaviorSubject<T> {
  constructor(initial: any) {
    super(<any>(initial));
  }

  emit(value?: T) { super.next(value); }
}

One drawback I can see is that it will emit the value of the initial argument as soon the related component is loaded in the DOM if no other value has been emitted yet.

Working example: Stackblitz

like image 90
ruth Avatar answered Aug 20 '26 06:08

ruth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!