Reputation: 655
I have an App made with Xamarin.Forms and ReactiveUI. Picture a View in this App where you have a kind of dropdown (actually a button that push another view where the user can filter and select one option) and when this "dropdown" is changed, I need to reload a list based on its value.
This "dropdown" won't start with some value, I need to make a async request, grab a value and then update the view.
The problem is, when I'm creating the command to load the documents:
LoadAllDocuments = ReactiveCommand.CreateFromTask<string, IEnumerable<Document>>(_ => m_service.GetAllDocumentsByTodoListAsync(SelectedTodoList.Id), canLoadAll, m_scheduler);
I need the Id from the SelectedToDoList, but this will be null at this point.
There's any way to delay this first execution of a command? Or maybe there's a better workflow to solve this?
Here is a sniped on how I'm doing it right now. Let me know if more information is needed.
LoadAllDocuments = ReactiveCommand.CreateFromTask<string, IEnumerable<Document>>(_ => m_service.GetAllDocumentsByTodoListAsync(SelectedTodoList.Id), canLoadAll, m_scheduler);
ChangeToDoListCommand = ReactiveCommand.CreateFromTask<DocumentListViewModel, bool>(vm => this.PushPageFromCacheAsync<ToDoListViewModel>((model) => model.ParentViewModel = this));
this.WhenActivated((CompositeDisposable disposables) =>
{
SelectedItem = null;
var SelectedTodoListChanged =
this
.WhenAnyValue(x => x.SelectedTodoList)
.Throttle(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler)
.Publish();
SelectedTodoListChanged
.Where(x => x == null)
.Subscribe(async _ => SelectedTodoList = await viewService.GetMyToDoListByVaultAsync(RuntimeContext.Current.VaultId))
.DisposeWith(disposables);
SelectedTodoListChanged
.Where(x => x != null)
.InvokeCommand(LoadAllDocuments)
.DisposeWith(disposables);
SelectedTodoListChanged.Connect();
LoadAllDocuments
.ObserveOn(m_scheduler)
.SubscribeOn(m_scheduler)
.Subscribe(list => AddViewsToList(list.ToList()))
.DisposeWith(disposables);
Upvotes: 0
Views: 754
Reputation: 178660
If I understand your question correctly, you need to ensure Id
is not null
before calling InvokeCommand
:
SelectedTodoListChanged
.Where(x => x?.Id != null)
.InvokeCommand(LoadAllDocuments)
.DisposeWith(disposables);
Perhaps a better option is to bake this knowledge into the command itself. Since InvokeCommand
respects the execution window of the command (as of RxUI 7, that is), if your command's CanExecute
is currently false
then InvokeCommand
will not actually invoke your command:
var canLoadAllDocuments = this
.WhenAnyValue(x => x.SelectedTodoList?.Id)
.Select(id => id != null);
LoadAllDocuments = ReactiveCommand.CreateFromTask<string, IEnumerable<Document>>(
_ => m_service.GetAllDocumentsByTodoListAsync(SelectedTodoList.Id), canLoadAll,
canLoadAllDocuments,
m_scheduler);
Now you can do this:
SelectedTodoListChanged
.InvokeCommand(LoadAllDocuments)
.DisposeWith(disposables);
Upvotes: 3