Reputation: 3753
I have an Angular application where I use RxJS BehaviorSubject to subscribe to a bool value that indicates an "in progress" status.
But I'm only interested in when the state changes and not the current state on subscription.
export class ProgressService {
private InProgress$ = new BehaviorSubject<boolean>(false);
constructor() {}
public getInProgressStateSubject() {
return this.InProgress$;
}
}
...
this.progressService.getInProgressSubject().subscribe((inProgress: boolean) => {
// This will be triggered in the moment of subscription as well as on state chages
if (inProgress) {
// Toggle on state
} else {
// Toggle off state
}
});
I like how it works, I just don't want it to trigger on subscription.
Are there any other similar operators in RxJS that can help me, or can I do it in any other way?
Thanks!
Upvotes: 14
Views: 10247
Reputation: 1
I implemented my own solution on C#: Please notice that I'm pretty sure it's not thread safe
public static class FutureObservable
{
public static IObservable<T> Future<T>(this IObservable<T> observable)
{
if (observable is FutureObservableWrapper<T> future)
return future;
return new FutureObservableWrapper<T>(observable);
}
private class FutureObservableWrapper<T> : IObservable<T>
{
private readonly IObservable<T> _source;
public FutureObservableWrapper(IObservable<T> source)
{
_source = source;
}
public IDisposable Subscribe(IObserver<T> observer)
{
var connectable = new ConnectableObserver(observer);
var disposable = _source.Subscribe(connectable);
connectable.Connect();
return disposable;
}
private class ConnectableObserver : IObserver<T>
{
private readonly IObserver<T> _observer;
private bool _connected;
public ConnectableObserver(IObserver<T> observer)
{
_observer = observer;
}
public void OnCompleted() => _observer.OnCompleted();
public void OnError(Exception error) => _observer.OnError(error);
public void OnNext(T value)
{
if (!_connected)
return;
_observer.OnNext(value);
}
public void Connect()
{
_connected = true;
}
}
}
}
Upvotes: 0
Reputation: 1597
Maybe you can use undefined
as initial value of BehaviorSubject
, and ignore it in your subscribe
method:
export class ProgressService {
private InProgress$ = new BehaviorSubject<boolean | undefined>(undefined);
constructor() {}
public getInProgressStateSubject() {
return this.InProgress$;
}
}
...
this.progressService.getInProgressSubject().subscribe((inProgress?: boolean) => {
if (inProgress !== undefined) {
// This won't be triggered on BehaviorSubject initialization but only when state is boolean
if (inProgress) {
// Toggle on state
} else {
// Toggle off state
}
}
});
Upvotes: 1
Reputation: 41
You can use ReplaySubject
with bufferSize 1 and they only have 1 value and the last.
Upvotes: 4
Reputation: 9124
I think there are several options:
Subject
skip(1)
to ignore the first valueUpvotes: 11