read

Quick one: Have you ever had to convert one layer model to the next one, and iterate through all the child elements to convert them as well? Not saying there is something wrong with that, but with a bit of RxJava magic we can make it look so much cooler.

Say you have your VeryCleanArchitecture™ data source

@NonNull
@Override
public Single<List<InmojiGroup>> get() {
    final List<InmojiCampaignCategory> stuff = StuffSDK.getStuff();
    final List<InmojiGroup> networkStuff = new ArrayList<>();
    for (InmojiCampaignCategory stuffCategory : stuff) {
        List<InmojiItem> items = new ArrayList<>();
        for (StuffItem stuffCategoryItem : stuffCategory.getStuffItems()) {
            items.add(NetworkStuffItem.from(stuffCategoryItem));
        }
        networkStuff.add(new NetworkStuffGroup(stuffCategory.getTitle(), 
                                                  items));
    }
    return Single.just(networkStuff);
}

Nice and easy. But it is not reactive enough. With a bit of salt and pepper, we can make it look VeryCleanMuchReactiveArchitecture™ worthy. However, notice that we need to access to some property of the original parent to compose our NetworkStuffGroup. A simple flatMap won’t do it, since we would only have access to the child items.

But what about doing like this:

@NonNull
@Override
public Single<List<NetworkStuffGroup>> get() {
    return Observable.from(StuffSDK.getStuff())
        .flatMap(
            stuffCategory ->
                Observable.from(stuffCategory.getStuffItems())
                    .map(NetworkStuffItem::from)
                    .toList(),
            (stuffCategory, networkStuffItems) 
                -> new NetworkStuffGroup(
                    stuffCategory.getTitle(), 
                    networkStuffItems)
        )
        .toList()
        .toSingle();
}

What the heck was that? Calling flatMap with two arguments? Well, it is not straightforward, but one of the flatMap overloads has a resultSelector as a second parameter.

We can use as resultSelector a function that takes the item before the flatMap and the grouped collection after the flatmap. This way we can easily create our network model group, without any confusing usage of Pair<T,U>.

And that’s all folks! May your code be reactive and your Observable never randomly unsubscribe.

Blog Logo

Guillermo Orellana


Published

Image

Guillermo Orellana

May contain traces of sarcasm and siesta

Back to Overview