Lawliet
Lawliet

Reputation: 131

Reactive UI Merging Observables to a ObservableAsPropertyHelper

I am trying to merge several Observables on a couple of ReactiveLists to create an ObservableAsPropertyHelper.

public class Model : ReactiveObject {
    ReactiveList<int> IngredientsEntities;
    // ...
    public int CostOfIngredients(...) { ... }
}

public class ViewModel : ReactiveObject {

    public Model Promotion;

    private ReactiveList<int> ingredientsQuantities;
    private ObservableAsPropertyHelper<int> cost;

    public Dictionary<..., ...> Ingredients;

    public int Cost {
        get { return cost.Value; }
    }

    public ViewModel() {
        // ...

        var ingredientsObservables = new[]
        {
            ingredientsQuantities.ItemChanged.Select(_ => Unit.Default),
            ingredientsQuantities.ShouldReset.Select(_ => Unit.Default),
            Promotion.IngredientsEntities.ItemChanged.Select(_ => Unit.Default),
            Promotion.IngredientsEntities.ShouldReset.Select(_ => Unit.Default),
        };
        Observable.Merge(ingredientsObservables)
            .Select(_ => promotion.CostOfIngredients(Ingredients))
            .ToProperty(this, x => x.Cost, out cost);

        Observable.Merge(ingredientsObservables)
            .Subscribe(_ =>
            {
                this.Log().Info("Ingredients change detected");
            });

    }
}

The log message fires, but the CostOfIngredients never gets called, and cost remains null. Am I doing something wrong here?

EDIT:

I modified ViewModel and this now works:

public class ViewModel : ReactiveObject {
    private int cost;
    public int Cost {
        get { return cost; }
        set { this.RaiseAndSetIfChanged(ref cost, value); }
    }

    // ...

   public ViewModel() {
        // ...
        var ingredientsObservables = new[]
            {
                ingredientsQuantities.ItemChanged.Select(_ => Unit.Default),
                ingredientsQuantities.ShouldReset.Select(_ => Unit.Default),
                Promotion.IngredientsEntities.ItemChanged.Select(_ => Unit.Default),
                Promotion.IngredientsEntities.ShouldReset.Select(_ => Unit.Default),
            };
            Observable.Merge(ingredientsObservables)
                .Subscribe(_ => Cost = promotion.CostOfIngredients(Ingredients));

   }
}

My understanding is that Select(_ => Unit.Default) creates an Observable for Unit.Default that never changes, thus never invoking any further Selects.

Upvotes: 3

Views: 1097

Answers (1)

Ana Betts
Ana Betts

Reputation: 74702

I think your problem is your use of ItemChanged - this only fires if you have item tracking enabled, and only when an item in your collection changes (i.e. myList[3].SomeProperty = "bar";). You probably want Changed, which will cover everything.

Upvotes: 3

Related Questions