I'm trying to convert an Observable into a BehaviorSubject. Like this:
a$ = new Observable() b$ = BehaviorSubject.create(new BehaviorSubject(123), a$) // 🔴
I have also tried:
a$ = new Observable() b$ = new BehaviorSubject(a$, 123) // 🔴
And:
a$ = new Observable() b$ = a$.asBehaviorSubject(123) // 🔴
And:
a$ = new Observable() b$ = a$.pipe( toBehaviorSubject(123) ) // 🔴
But none of these works. For now I have to implement like this:
a$ = new Observable() b$ = new BehaviorSubject(123) a$.subscribe(b$) // 🔵
This would be a little bit ugly in a class:
class Foo() { a$ = new Observable() // Actually, a$ is more complicated than this. b$ = new BehaviorSubject(123) constructor() { this.a$.subscribe(this.b$) } }
So, is there a simpler way to convert an Observable to a BehaviorSubject without using class constructor?
This is my real case:
export class Foo { autoCompleteItems$ = new BehaviorSubject<string[]>(null) autoCompleteSelected$ = new BehaviorSubject<number>(-1) autoCompleteSelectedChange$ = new Subject<'up'|'down'>() constructor() { this.autoCompleteItems$.pipe( switchMap((items) => { if (!items) return EMPTY return this.autoCompleteSelectedChange$.pipe( startWith('down'), scan<any, number>((acc, value) => { if (value === 'up') { if (acc <= 0) { return items.length - 1 } else { return acc - 1 } } else { if (acc >= items.length - 1) { return 0 } else { return acc + 1 } } }, -1) ) }) ).subscribe(this.autoCompleteSelected$) } doAutoComplete = () => { const item = this.autoCompleteItems$.value[this.autoCompleteSelected$.value] // do something with `item` } }
BehaviorSubject is both observer and type of observable. BehaviorSubject always need an initial/default value. Every observer on subscribe gets current value. Current value is either latest value emitted by source observable using next() method or initial/default value.
Observable is a Generic, and BehaviorSubject is technically a sub-type of Observable because BehaviorSubject is an observable with specific qualities. An observable can be created from both Subject and BehaviorSubject using subject.
If you need to make your observable shared and replay the values, use observable. pipe(shareReplay(1)) . If you want to have the subscriber functionality as well, you need to use the ReplaySubject subscribed to the original Observable observable. subscribe(subject); .
No need to convert it.
Just create a subject and attach observable to it with : obs.subscribe(sub)
example:
var obs = new rxjs.Observable((s) => {setTimeout(()=>{s.next([1])} , 500)}) //observable var sub = new rxjs.BehaviorSubject([0]) //create subject obs.subscribe(sub) //<----- HERE ----- attach observable to subject setTimeout(() => {sub.next([2, 3])}, 1500) //subject updated sub.subscribe(a => console.log(a)) //subscribe to subject
Note: obs.subscribe(sub)
is equivalent to :
obs.subscribe({ next: v => sub.next(v), error: v => sub.error(v), complete: () => sub.complete() })
Run it online
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With