Best RX Practice: Choose With Side Effect or Use Subscription?
I am converting events (paging events from buttons) to IObservable and receiving the result from the service asynchronously.
As a side effect, I need to update the child mode. I have two solutions:
-
Side effect when choosing:
//Converting events to a "stream" of search results. IObservable<SearchResult> resultsFromPageChange = Observable.FromEventPattern<EventArgs>(this, "PageChangedEvent") .Throttle(TimeSpan.FromMilliseconds(500)) .Select(async ev => { var input = new SearchResultInput() { PageSize = PageSize, PageIndex = PageIndex, SearchOptions = _currentSearchOptions, SearchText = SearchText.Value }; var result = await GetPagedComponents(input); //Side effect ActivateAttributesView(result.Components.FirstOrDefault()); return result; }).Switch(); //flatten and take most recent.
-
Do side effect on subscription:
//Converting events to a "stream" of search results. IObservable<SearchResult> resultsFromPageChange = Observable.FromEventPattern<EventArgs>(this, "PageChangedEvent") .Throttle(TimeSpan.FromMilliseconds(500)) .Select(async ev => { var input = new SearchResultInput() { PageSize = PageSize, PageIndex = PageIndex, SearchOptions = _currentSearchOptions, SearchText = SearchText.Value }; return await GetPagedComponents(input); }).Switch(); //flatten and take most recent. //Do side effect in the subscribe resultsFromPageChange.Subscribe(x => { if (x != null) ActivateAttributesView(x.Components.FirstOrDefault()); });
Both methods work. Which solution should I choose and why?
THX.
Because the question is why this creates values at all, here's the complete code:
//Converting events to a "stream" of search results.
IObservable<SearchResult> resultsFromPageChange = Observable.FromEventPattern<EventArgs>(this,
"PageChangedEvent")
.Throttle(TimeSpan.FromMilliseconds(500))
.Select(async ev =>
{
var input = new SearchResultInput()
{
PageSize = PageSize,
PageIndex = PageIndex,
SearchOptions = _currentSearchOptions,
SearchString = SearchString.Value
};
return await SearchComponentsPaged(input);
}).Switch(); //flatten and take most recent.
SearchString = new ReactiveProperty<string>(""); //Bound to TextBox.Text
//Create a "stream" of search results from a string given by user (SearchString)
SearchResult = SearchString
.SetValidateNotifyError(s => _componentDataService.ValidateSearchStringLength(s).Errors)
.Throttle(TimeSpan.FromMilliseconds(500))
.Select(async term =>
{
var input = new SearchResultInput()
{
PageSize = PageSize,
PageIndex = PageIndex,
SearchOptions = _currentSearchOptions,
SearchString = term
};
return await SearchComponentsPaged(input);
})
.Switch()
.Merge(resultsFromPageChange) //Merge the result of paging and text changing.
.ToReactiveProperty();
//Update Attributes view
SearchResult.Subscribe(searchResult =>
{
if (searchResult != null)
{
ActivateAttributesView(searchResult.Components.FirstOrDefault());
SearchResult.Value.TotalItemsCount = searchResult.TotalItemsCount;
}
});
This is actually sending a search query to the DB when the search string changes and getting page-by-page results OR getting another page with the same search string when the PageChangedEvent page is received. Does .Merge (...) include a subscription?
+3
source to share
2 answers