Skip to content

Instantly share code, notes, and snippets.

@Fasteroid
Last active July 11, 2024 19:39
Show Gist options
  • Save Fasteroid/9926088c62d78066ff79804511cf6b7c to your computer and use it in GitHub Desktop.
Save Fasteroid/9926088c62d78066ff79804511cf6b7c to your computer and use it in GitHub Desktop.
Ever wanted an EventEmitter you can't miss if you subscribe late?
import { EventEmitter } from "@angular/core";
import { Subscription } from "rxjs";
export class StateEmitter<T> extends EventEmitter<T> {
private ready: boolean = false;
private snapshot: T | undefined = undefined;
get value() { return this.snapshot; }
constructor(first?: T) {
super();
super.subscribe( snapshot => {
this.ready = true;
this.snapshot = snapshot
}) // when it emits, save the snapshot
if( arguments.length > 0 ) this.emit(first); // if we have a first value, emit it
}
// run only once
onValueReady(callback: (value: T) => void){
if(this.ready){ // ready immediately, just do it
callback(this.snapshot!);
}
else { // wait for it... legen...
const sub = this.subscribe(value => { // ...dary
sub.unsubscribe();
callback(value);
})
}
}
onValueMeetsCondition(condition: (value: T) => boolean, callback: (value: T) => void){
if( this.ready && condition(this.snapshot!) ){ // ready immediately, just do it
callback(this.snapshot!);
}
else { // wait for it... legen...
const sub = this.subscribe(value => { // ...dary
if( condition(value) ){
sub.unsubscribe();
callback(value);
}
})
}
}
override subscribe(callback: (value: T) => void): Subscription {
if(this.ready){ // we missed the last emit, so we need to catch up
callback(this.snapshot!);
}
return super.subscribe(callback);
}
quietEmit(value: T){
this.snapshot = value;
}
}
@Fasteroid
Copy link
Author

Angular 18 has signals and I think they replicate this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment