Smirnov Denis
Smirnov Denis

Reputation: 45

Data from api to ObservableCache with DynamicData with periodically update

For example I have api to get list of Items:

Task<ICollection<Item>> GetItemsAsync();

I want to work with Items with ObservableCache<Item, int>.

So, I created IItemsService:

IObservableCache<Item, int> Items { get; }

with an implementation:

private IObservableCache<Items, int> _items;

public IObservableCache<Items, int> Items => _items ?? (_items = Create().AsObservableCache().Publish().RefCount());

private IObservable<IChangeSet<Items, int>> Create()
{
    return ObservableChangeSet.Create<Items, int>(cache =>
    {
        var timer = Observable.Interval(TimeSpan.FromSeconds(1))
            .SelectMany(_ => _api.GetItemsAsync())
            .Retry()
            .Subscribe(matchInfos => cache.EditDiff(matchInfos, EqualityComparer<MatchInfo>.Default));

        return timer;
    }, item => item.Id);

Then I use this service in view model to show items:

_service.Connect()
    .Transform(item => new ItemViewModel(item))
    .Bind(out items)
    .Subscribe(_ => Initialized = true);

Initialized property need to show/hide loading indicator.

I have a few questions:

  1. Is this a good way?
  2. I need to show "There is no Items" when Items Count is 0 and Initialized property is true. But if server return 0 items - ObservableCache will not raise notify, so Initialized property will be false. What can I do with that?
  3. When I dispose all subscriptions, the timer doesn't stop. I use RefCount() but it doesn't help.

Upvotes: 3

Views: 1576

Answers (1)

Roland Pheasant
Roland Pheasant

Reputation: 1231

  1. Using ObservableChangeSet.Create is a good way as it is flexible and also allows for retry / repeat logic. However Publish().RefCount() cannot work in your example as you are applying it to the cache and not to observable change set. Are you looking to lazy load the cache? If so I can update this answer with some examples.

  2. The answer from Glenn is correct. For optimisations reasons empty change notifications are suppressed in Dynamic Data. This restriction is in the process of being removed. See issue #206.

  3. There are unit tests to cover the disposal of resources created byObservableChangeSet. See ObservableChangeSetFixture.cs so I suspect the reason for the timer not being disposed is that the cache itself has not been disposed and it keeping the subscription alive.

Upvotes: 2

Related Questions