A ViewModel using ReactiveUI 6 that loads and sends data Most of the Rx Compelling Examples™ load and store data locally, which I don't find that Compelling.

I spent some time coming up with how to best perform the following actions but want to make sure I am not Doing It Wrong™.

Here are the cases I am trying to solve:


Load data from cache and remote server when view model is instantiated
Save data to server when UI interaction happens (some button press)
Handle error cases (network down)


Some items I am trying to avoid:


Errors being swallowed (async in ctor for example)
Incorrect use of Rx patterns (is there a more 'correct' way)
Loss of data either through out of sync lists, not using cache correct, other.




public class CommonViewModel : ReactiveObject, IRoutableViewModel
{
    private readonly RemoteHttpService _remoteClient;

    private ReactiveList&lt;Item&gt; _items;
    public ReactiveList&lt;Item&gt; ItemsFromServer
    {
        get { return _items; }
        set { this.RaiseAndSetIfChanged(ref _items, value); }
    }

    public ReactiveCommand&lt;List&lt;Item&gt;&gt; LoadItems{ get; protected set; }
    public ReactiveCommand&lt;object&gt; SendItemsToServerCommand { get; protected set; }

    public string UrlPathSegment
    {
       get { return "CommonViewModel View"; }
    }

    public IScreen HostScreen { get; private set; }

    public CommonViewModel(IScreen screen)
    {
        HostScreen = screen;
        ItemsFromServer = new ReactiveList&lt;Item&gt;();
        _remoteClient = new RemoteHttpService(); //using refit and polly behind the scenes.

        SendItemsToServerCommand = ReactiveCommand.CreateAsyncTask((_, ctx) =&gt; InternalSendItemsToServer());
        SendItemsToServerCommand.ThrownExceptions.Subscribe(ex =&gt; UserError.Throw("Could not send data to server", ex));

        LoadItems = ReactiveCommand.CreateAsyncObservable(_ =&gt;     this.InternalGetItemsFromCacheAndServer());
        LoadItems.Subscribe(list =&gt;
        {
             _items.Clear();
            foreach (var item in list){
                 //using AddRange throw Presentation Exception
                _items.Add(item);
            }
         });
        LoadItems.ThrownExceptions.Subscribe(ex =&gt; UserError.Throw("Could not get data from server"));
        LoadItems.ExecuteAsyncTask();
    }

    private IObservable&lt;List&lt;Item&gt;&gt; InternalGetItemsFromCacheAndServer()
    {
        return BlobCache.LocalMachine.GetAndFetchLatest("items",
        InternalGetRemoteItems,
        dt =&gt; true,
        RxApp.MainThreadScheduler.Now + TimeSpan.FromMinutes(5));
    }

    private async Task&lt;List&lt;Item&gt;&gt; InternalGetRemoteItems()
    {
        var conferences = await _remoteClient.GetItems().ConfigureAwait(false);
        return conferences;
    }

    private async Task&lt;object&gt; InternalSendItemsToServer()
    {
        var itemsToSendToServer = ItemsFromServer.SomeLinq().Maybe();
        return await _remoteClient.SendDataToServer(itemsToSendToServer);
    }
}
Sorry to disappoint, but you did everything right! This is a quite good example of using RxUI, Akavache, and Refit together. 

The only thing I would change, is to not immediately call LoadItems.ExecuteAsyncTask in the ViewModel constructor. Invoking this in the VM constructor means that your VM class becomes more difficult to test, because you always have to mock out the effects of calling LoadItems, even if the thing you are testing is unrelated.

Instead, I always call these commands in the View constructor, something like:

this.WhenAnyValue(x =&gt; x.ViewModel.LoadItems)
    .SelectMany(x =&gt; x.ExecuteAsync())
    .Subscribe();


This means that any time we get a new ViewModel, we execute LoadItems, which is what we want when the app is running, but not what we want in every unit test.