← Back to all articles

Language support for CombineLatest would be nice

CombineLatest is very useful for orchestrating parallel asynchronous/observable requests. For example;

Observable.Return("James")
.CombineLatest(Observable.Return(28), (name, age) => new { name, age })
.CombineLatest(Observable.Return("My Street"), (_, address) => new { _.name, _.age, address })
.CombineLatest(Observable.Return("6076"), (_, postcode) => new { _.name, _.age, _.address, postcode });

As you can see however as the number of observables in the query grow, there is a fair bit of monkeying around required to map each anonymous type to the next. One solution would be to extend query comprehension syntax to support this extension method.

from name in Observable.Return("James")
latest age in Observable.Return(28)
latest address in Observable.Return("My Street")
latest postcode in Observable.Return("6076")
select new{ name, age, address, postcode }

If you agree, throw your support in by clicking on this LINQ 😉. In the meantime, if you can't get your head around the code above, you can use tuples as an alternative.

(Some new extension methods)

static class Ex
{
    public static IObservable<Tuple<T1, T2>> CombineLatestWithTuple<T1, T2>(this IObservable<T1> source, IObservable<T2> source2)
    {
        return source.CombineLatest(source2, (t1, t2) => new Tuple<T1, T2> { Value1 = t1, Value2 = t2 });
    }

    public static IObservable<Tuple<T1, T2, T3>> CombineLatestWithTuple<T1, T2, T3>(this IObservable<Tuple<T1, T2>> source, IObservable<T3> source2)
    {
        return source.CombineLatest(source2, (t, t3) => new Tuple<T1, T2, T3> { Value1 = t.Value1, Value2 = t.Value2, Value3 = t3 });
    }

    public static IObservable<Tuple<T1, T2, T3, T4>> CombineLatestWithTuple<T1, T2, T3, T4>(this IObservable<Tuple<T1, T2, T3>> source, IObservable<T4> source2)
    {
        return source.CombineLatest(source2, (t, t4) => new Tuple<T1, T2, T3, T4> { Value1 = t.Value1, Value2 = t.Value2, Value3 = t.Value3, Value4 = t4 });
    }
}

This allows you to write the query like this;

Observable.Return("James")
.CombineLatestWithTuple(Observable.Return(29))
.CombineLatestWithTuple(Observable.Return("My Street"))
.CombineLatestWithTuple(Observable.Return("6076"))
.Select(t => new
{
    Name = t.Value1,
    Age = t.Value2,
    Address = t.Value3,
    Postcode = t.Value4
});

I personally don't mind the original syntax but its here if you want it.

Cheers,
James

Comments