Reputation: 6142
I was wondering if following scenario could be fixed by using RX?
I have a REST service call that has an input parameter distance and loads data, this data is than inserted in the ObservableCollection of the ViewModel so that the View will show the data... Pseudo code like this:
public async Task<int> LoadData(int distance)
{
this.ListOnUI.Clear();
var dataList = await Task.Run(() => _dataService.GetListAsync(distance));
foreach(var dataItem in dataList)
{
this.ListOnUI.Add(dataItem);
}
return dataList.Count;
}
Now this small code snippet is wrapped inside a method, that returns the count of the dataList. What I do with that count, check if the amount returned is at least 20, if not I recall the method with a larger distance.
So what is wrong with this setup...
So my gut feeling is telling me this could be solved by using RX somehow, so that we 'chunk' load/add the UI list.
But my knowledge of RX is not good enough to solve it... so any ideas?
REMARK: When we call the LoadData service we are getting a JSON string that is then mapped to a collection of DataItems, so if we not clear the UI ObservableCollection and would just Add them with each itteration... we would get the same item multiple times in the list because it are newly constructed objects ( although with the same data ).
Upvotes: 0
Views: 482
Reputation: 6142
Thanks to the suggested answers, it got me thinking about using a Sortable Observable collection and just adding the items as they come in!
I've used the example explained by Andrea here: http://www.xamlplayground.org/post/2010/04/27/Keeping-an-ObservableCollection-sorted-with-a-method-override.aspx
But used the Binary search option noted in the comments of the blog post! To be sure we don't stop the code when we find items already in the list, I just commented out the Throw Exception.
For this to work I only needed to implement IComparable.
Upvotes: 0
Reputation: 29786
Modified to calculate a list delta each time. For contains to work correctly you just need to implement Equals appropriately on the items returned form GetListAsync. Perhaps by a contrived key comparison as SB Dev suggested. Not sure there's much Rx can bring to the table in the context of the question.
public async Task<int> LoadData(int distance)
{
int count = 0;
IList<object> dataList = null;
while (count < 20)
{
dataList = await Task.Run(() => _dataService.GetListAsync(distance));
count = dataList.Count;
var newItems = dataList.Except(ListOnUI).ToList();
var removedItems = ListOnUI.Except(dataList).ToList();
removedItems.ForEach(x => ListOnUI.Remove(x));
newItems.ForEach(ListOnUI.Add);
}
return count;
}
Assuming you are using an ObservableCollection
for your list, see Sort ObservableCollection - what is the best approach? for sorting.
Upvotes: 1
Reputation: 531
Is there any Key inside the data objects? If so you could check in your foreach wether the object is already contained and only add it if it's not. That way you wouldn't have to clear it (together with all side effects).
If there is no key you could create one by hashing the title + distance or whatever data fields you have that could together uniquely identify your data item and use that for the check.
Don't know wether there is a better way with reactive extensions but it should solve your case at least.
Upvotes: 1