WhenAnyValue with null propogation, how to init and monitor for other values? #3770
-
| 
         There is a proposed workaround for null propagation. However it doesn't trigger (at all) if expression has null value in the chain. Which leads to 2 problems: 
 I made a simple test to demonstrate the issue. Show codepublic class Program
{
    static void Main(string[] args)
    {
        var parent = new Parent();
        parent.WhenAnyValue(o => o.Child, o => o.Trigger, o => o.Child!.Property)
            .Subscribe(o => Console.WriteLine($"A: {o.Item1}"));
        parent.WhenAnyValue(o => o.Child, o => o.Trigger, o => o.Child!.Property)
            .StartWith((null, false, null))
            .Subscribe(o => Console.WriteLine($"B: {o.Item1}"));
        parent.WhenAnyValue(o => o.Trigger)
            .CombineLatest(parent.WhenAnyValue(o => o.Child, o => o.Child!.Property))
            .Subscribe(o => Console.WriteLine($"C: {o.Second.Item1}"));
        parent.WhenAnyValue(o => o.Child, o => o.Trigger)
            .Subscribe(o => Console.WriteLine($"D: {o.Item1}"));
        Console.WriteLine("Trigger");
        parent.Trigger = true;
        Console.ReadKey();
    }
}
public class Parent : ReactiveObject
{
    [Reactive]
    public Child? Child { get; set; }
    [Reactive]
    public bool Trigger { get; set; }
    public override string ToString() => $"{Trigger} {Child}";
}
public class Child : ReactiveObject
{
    [Reactive]
    public string? Property { get; set; }
    public override string ToString() => $"Child {Property}";
}I have to monitor for  Run the test and the output will be: 
 In other words: 
 QuestionHow to monitor for   | 
  
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
| 
         Found a workaround! For null propagated property it's absolutely necessary to create an extra property to monitor only for value changes of that property and then use that extra property instead of null-forgiving operator. Then  To fix code from first post: 
 [ObservableAsProperty]
public string? ChildProperty { get; }
 // this subscription only monitors for child property value
// it will stop working as any WhenAnyValue with null-forgiving operator when parent in expression is null
// but we don't care, as we only need correct value when parent is not null
parent.WhenAnyValue(o => o.Child, o => o.Child!.Property, (child, property) => property)
    .ToPropertyEx(parent, o => o.ChildProperty);
// this subscription is bullet proof and will correctly rise on any change!
parent.WhenAnyValue(o => o.Child, o => o.Trigger, o => o.ChildProperty)
    .Subscribe(o => Console.WriteLine($"E: {o.Item1}"));
 parent.Trigger = !parent.Trigger; // E:
parent.Child = new(); // E: Child
parent.Child.Property = "123"; // E: Child 123
parent.Child = null; // E: | 
  
Beta Was this translation helpful? Give feedback.
Found a workaround!
For null propagated property it's absolutely necessary to create an extra property to monitor only for value changes of that property and then use that extra property instead of null-forgiving operator. Then
WhenAnyValueworks for all scenarios.To fix code from first post:
parent(it can be anywhere, but makes the most sense to be there):