Last active
July 11, 2024 19:39
-
-
Save Fasteroid/9926088c62d78066ff79804511cf6b7c to your computer and use it in GitHub Desktop.
Ever wanted an EventEmitter you can't miss if you subscribe late?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Angular 18 has signals and I think they replicate this