I have a User model that has an IObservable<int> property. This property is backed by a BehaviorSubject that is initialized with a certain value. How can I get the current value of the observable, without having to expose another property that accesses the .Value property on the underlying BehaviorSubject?
This is the sample model to consider:
class User
{
private readonly BehaviorSubject<int> mySubject;
public User()
{
mySubject = new BehaviorSubject<int>(100);
}
public IObservable<int> Value => mySubject.DistinctUntilChanged();
public void SomeMethod(int level)
{
mySubject.OnNext(level);
}
}
Notice that I have a method that calls OnNext on the subject with the specified value. This is already strange to me, it would be better if I could just treat the Value observable as a get and set property but alas...
On another part of my code, I need to imperatively get the current value for a given user, and I can't seem to find a way to do that from the IObservable interface directly. I tried using both the Latest and MostRecent methods, but they seem to do different things than what I would expect. When trying both, my application blocks indefinitely.
The only way I found to properly expose the value was to create another property for the "current" value, like this:
public int CurrentValue => mySubject.Value;
I don't like this because it feels to me that I'm being redundant. Is there a better way to expose the current value of the observable so that external code can just get the value and do what it wants with it? For that matter, as I commented earlier, I'm also not very happy having another method to mutate the value. It makes the interface of the object cumbersome in my view. In knockoutjs for instance, I can get and set the value just by "calling" the observable, which seems simpler. In this case this would be equivalent to Value().
You can always do one of these, depending on whether you're in an async context or not:
var value = await user.Value.FirstAsync();
var value = user.Value.First();
Alternatively, you can do something like this:
class User
{
private readonly BehaviorSubject<int> valueSubject;
public int Value
{
get { return valueSubject.Value; }
set { valueSubject.OnNext(value); }
}
public IObservable<int> ValueChanged => valueSubject.DistinctUntilChanged();
public User()
{
valueSubject = new BehaviorSubject<int>(100);
}
}
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