0

I'm trying to set an initial value to the public ReactiveProperty<string> ConnectionStatus.

public ViewModelConstructor()
{
    ConnectionStatus = Observable
                    .Interval(RefreshInterval)
                    .Select(x => Observable.FromAsync(() => networkDiscovererService.CanDiscoverAsync("192.168.1.1", RequestTimeout)))
                    .Concat()
                    .Select(isConnected => isConnected ? $"connected" : $"not connected")
                    .ToReactiveProperty();
}

Even if I'm trying to instantiate it like this

public ReactiveProperty<string> ConnectionStatus { get; } =
            new ReactiveProperty<string>("Checking connectivity...");

It's still empty until the observable returns something.

Any ideas? I'm using this library.

Gabriel Robert
  • 3,012
  • 2
  • 18
  • 36

1 Answers1

1

To get initial value on subscribe (like behaviorSubject, or Replay(1)) using ReactiveProperty ctor:

    [Test]
    public void ShouldReturnAValuOnSubscribe()
    {
        var testScheduler = new TestScheduler();
        var testableObserver = testScheduler.CreateObserver<int>();

        var reactiveProperty = new ReactiveProperty<int>(30);
        reactiveProperty.Subscribe(testableObserver);

        Assert.AreEqual(30, testableObserver.Messages.Single().Value.Value);
    }

To get initial value on subscribe (like behaviorSubject, or Replay(1)) using .ToReactiveProperty():

    [Test]
    public void ShouldReturnAValuOnToReactiveProperty()
    {
        var testScheduler = new TestScheduler();
        var testableObserver = testScheduler.CreateObserver<int>();

        var reactiveProperty = Observable.Never<int>().ToReactiveProperty(40);
        reactiveProperty.Subscribe(testableObserver);

        Assert.AreEqual(40, testableObserver.Messages.Single().Value.Value);
    }

NOT to get initial value on subscribe - change ReactivePropertyMode:

    [Test]
    public void ShouldNotReturnAnInitialValue_WhenModeIsNone_AndOnSubscribe()
    {
        var testScheduler = new TestScheduler();
        var testableObserver = testScheduler.CreateObserver<int>();

        var reactiveProperty = new ReactiveProperty<int>(30, ReactivePropertyMode.None);
        reactiveProperty.Subscribe(testableObserver);

        Assert.IsEmpty(testableObserver.Messages);
    }

Basically, what you're looking for is initial value and ReactivePropertyMode.RaiseLatestValueOnSubscribe flag.

In the first case you forgot to provider ToReactiveProperty() with initial value (e.g. ToReactiveProperty(30))

It should've worked for you in the second case - the mode is set to ReactivePropertyMode.RaiseLatestValueOnSubscribe by default (check ShouldReturnAValuOnSubscribe). Try to set the mode explicitly (like in ShouldNotReturnAnInitialValue_WhenModeIsNone_AndOnSubscribe).

I used ReactiveProperty 3.6.0.

btw, It's not a very good idea to test a connection based on timer :)

aderesh
  • 927
  • 10
  • 22
  • Thank you for the hints. Do you have any recommendations regarding timer-based connection tester? It's for real-time streaming data from a device on the network, so I need to notify the user if the device is unavailable. – Gabriel Robert Jan 01 '18 at 17:00
  • Hi @GabrielRobert. I don't know the internals of your networkDiscovererService class but usually this kind of classes have something like Connected/Disconnected events to report status. Timer-based connectivity should be your last resort in this case :) – aderesh Jan 02 '18 at 01:51
  • It’s just a ping service targeting an IP. I trigger a ping every few seconds to make sure it’s always reachable. To be reachabable, the user need to be on the same device’s wifi. – Gabriel Robert Jan 02 '18 at 12:15