Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling lists with RxJava and Retrofit in android

I have couple of api calls to make (sequentially, asynchronously) and some of them returns lists. My api interface is given below.

@GET("/users/settings")
Observable<UserWrapper> getUserSettings();

@GET("/{username}/collections")
Observable<List<Item>> getItems(@Path("username") String userName);

@GET("/item/{id}")
Observable<ItemInfo> getItemInfo(@Path("id") int id);

@GET("/{username}/friends")
Observable<List<Friend>> getFriends(@Path("username") String userName);

Here's what I want to do sequentially:

  • Get UserWrapper by calling getUserSettings()
  • Save the user by calling saveUser(userWrapper)
  • Get user's items by calling getItems(userWrapper.getUserName())
  • Get each item's information by calling getItemInfo(item.getId())
  • Save each itemInfo by calling saveItem(itemInfo)
  • Get user's friends by calling getFriends(userWrapper.getUserName())
  • Save each friend by calling saveFriend(friend)

Now I am new to RxJava and do not know how to handle lists. I watched one of Jake Wharton's slides and found that he uses a function flattenList() but I don't know its definition. It would be great if you can help composing this chain.


Update 1

This is as far I've gotten now:

mApiService.getUserSettings()
            .map(this::saveUser)
            .flatMap(userWrapper -> mApiService.getItems(userWrapper.getUserName()));
            .flatMapIterable( ? "How to iterate for each item" ? );

Update 2

I am trying to write something like this

mApiService.getUserSettings()
    .map(this::saveUser)
    .flatMap(userWrapper -> mApiService.getItems(userWrapper.getUserName()))
    .someMethodToIterateThroughEachItem(item -> mApiService.getItemInfo(item))
    .map(this::saveItem)
    .someMethodThatCanCallUserWrapperAgain(userWrapper -> mApiService.getFriends(userWrapper.getUserName()))
    .someMethodToIterateThoughEachFriend(friend -> saveFriend(friend))
like image 604
Raquib-ul Alam Avatar asked Dec 29 '14 17:12

Raquib-ul Alam


People also ask

What is the difference between RxJava and retrofit?

Rx gives you a very granular control over which threads will be used to perform work in various points within a stream. To point the contrast here already, basic call approach used in Retrofit is only scheduling work on its worker threads and forwarding the result back into the calling thread.

What is the difference between coroutines and RxJava?

RxJava can be used with any Java-compatible language, whereas Kotlin coroutines can only be written in Kotlin. This is not a concern for Trello Android, as we are all-in on Kotlin, but could be a concern for others. (Note that this just applies to writing code, not consuming it.

What is retrofit used for in Android?

Retrofit is type-safe REST client for Android and Java which aims to make it easier to consume RESTful web services.


1 Answers

RxJava has added flatMapIterable. So you don't need flattenList now. E.g.,

  Observable<UserWrapper> o =
       getUserSettings()
       .doOnNext(this::saveUser)
       .flatMap(user -> getItems(user.getUserName())
                        .flatMapIterable(items -> items)
                        .flatMap(item -> getItemInfo(item.getId()))
                        .doOnNext(this::saveItem)
                        .toList()
                        .map(ignored -> user))
        .flatMap(user -> getFriends(user.getUserName())
                         .flatMapIterable(friends -> friends)
                         .doOnNext(this::saveFriend)
                         .toList()
                         .map(ignored -> user)
        );
    o.subscribe(...);
like image 186
zsxwing Avatar answered Sep 19 '22 12:09

zsxwing