I am trying to find some 'best practice' sample how to use Xamarin.Forms, ReactiveUI and Akavache in realworld scenario. Lets say there is simple page representing Customer Detail. It should retrieve data from server when activated (navigated to). I like the idea of GetAndFetchLatest extension method from Akavache so I would like to use it.
I ended up with something like this:
public class CustomerDetailViewModel : ViewModelBase //(ReactiveObject, ISupportsActivation)
{
private readonly IWebApiClient webApiClient;
public Customer Customer { get; }
public ReactiveCommand<Unit, Unit> GetDataCommand { get; }
public CustomerDetailViewModel(Customer customer, IWebApiClient webApiClient = null)
{
this.Customer = customer;
this.webApiClient = webApiClient ?? Locator.Current.GetService<IWebApiClient>();
GetDataCommand = ReactiveCommand.CreateFromTask(GetData);
}
private Task GetData()
{
BlobCache.LocalMachine.GetAndFetchLatest($"customer_{Customer.Id.ToString()}",
() => webApiClient.GetCustomerDetail(Customer.Id))
.Subscribe(data =>
{
CustomerDetail = data;
});
return Task.CompletedTask;
}
private CustomerDetail customerDetail;
public CustomerDetail CustomerDetail
{
get => customerDetail;
set => this.RaiseAndSetIfChanged(ref customerDetail, value);
}
}
DTOs
public class Customer
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class CustomerDetail
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
View binding
this.WhenActivated(disposables =>
{
this.OneWayBind(this.ViewModel, x => x.Customer.Name, x => x.nameLabel.Text)
.DisposeWith(disposables);
this.OneWayBind(this.ViewModel, x => x.CustomerDetail.Description, x => x.descriptionLabel.Text)
.DisposeWith(disposables);
this.ViewModel?.GetDataCommand.Execute().Subscribe();
}
But I think this is not 100% bullet proof. There are some possible problems with this:
- Is it ok to call
this.ViewModel?.GetDataCommand.Execute().Subscribe();
inthis.WhenActivated(d => ...)
on the view when I want to load data on activation? - Binding to
CustomerDetail.Description
can causeNullReferenceException
am I right? Or is it safe? - I want to do somethin like: "If there is
CustomerDetail
, showCustomerDetail.Name
. When its not loaded yet, showCustomer.Name
". Do I need to make specific Property on ViewModel because of it? - How to indicate loading?
- Am I missing something important here? Some other problems I can have with this?