Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: ToObservableOptional Extension Method for IObservable<IChangeSet<TObject, TKey>> #740

Conversation

dwcullop
Copy link
Member

@dwcullop dwcullop commented Oct 15, 2023

Description

This PR adds ToObservableOptional, an extension method for observable changesets that allows the consumer to create an IObservable<Optional<TObject>> from an IObservable<IChangeSet<TObject, TKey>> which emits the latest value associated with the specified key whenever that value is updated.

This method is the inverse counterpart to the EditDiff method from #739 (which yields an IObservable<IChangeSet<TObject,TKey>> given an IObservable<Optional<TObject>>.

Parameters

Optional boolean initialOptionalWhenMissing allows the consumer to specify if they want to receive an initial Optional.None if the value is not immediately added to the changeset at the time of subscription.

This extension method will also optionally accept an IEqualityComparer that will be used to compare the values of the changeset so that duplicate values are never emitted sequentially.

Example

Among the many uses, this method can be used in conjunction with FilterOnObservable from #735 in order to filter items in one changeset using the value of a specific Key in a child changeset.

interface IItem
{
   string Id { get; }
   IObservableCache<string, string> Properties { get; }
}

Optional<int> ParseInt(str => int.TryParse(str, out int val) ? Optional.Some(val) : Optional.None<int>());

// Create an Observable bool that will fire true whenever the rating property
// in the given IItem's Property cache is changed to something that is at least minRating
IObservable<bool> CreateRatingFilter(IItem item, int minRating) =>
    item.Properties
        .Connect()
        .ToObservableOptional("Rating")
        .Select(opt => opt.Convert(ParseInt)
                          .Convert(rating => rating >= minRating)
                          .ValueOrDefault());

var collection = new SourceCache<IItem, string>(item => item.Id);

var bestThingsSub = collection
                           .Connect()
                           .FilterOnObservable(item => CreateRatingFilter(item, 9))
                           .OnItemAdded(item => HighlightHighRating(item))
                           .OnItemRemoved(item => CalloutRatingDrop(item))
                           .Subscribe();

@codecov
Copy link

codecov bot commented Oct 15, 2023

Codecov Report

Merging #740 (5cae803) into main (f1da1b1) will decrease coverage by 0.40%.
Report is 1 commits behind head on main.
The diff coverage is 90.62%.

❗ Current head 5cae803 differs from pull request most recent head 8d13f19. Consider uploading reports for the commit 8d13f19 to get more accurate results

@@            Coverage Diff             @@
##             main     #740      +/-   ##
==========================================
- Coverage   72.22%   71.82%   -0.40%     
==========================================
  Files         217      217              
  Lines       11057    10932     -125     
==========================================
- Hits         7986     7852     -134     
- Misses       3071     3080       +9     
Files Coverage Δ
src/DynamicData/Cache/ObservableCacheEx.cs 50.97% <90.00%> (-0.57%) ⬇️
...DynamicData/Cache/Internal/ToObservableOptional.cs 90.90% <90.90%> (ø)

... and 4 files with indirect coverage changes

@RolandPheasant RolandPheasant merged commit cfa4ec1 into reactivemarbles:main Oct 16, 2023
1 check passed
@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 31, 2023
@dwcullop dwcullop deleted the feature/changeset-as-observable-optional branch November 23, 2023 00:57
@dwcullop dwcullop self-assigned this Dec 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants