Deuce
Deuce

Reputation: 21

Combining API responses in RxJava where one of the APIs returns a list

I'm trying to use RxJava to combine the responses from two API calls. The scenario is the following: The first API call returns a list of User objects. Each User object contain a postcode, but they do not contain a city name. To get the city name a second API is called, with the parameter being the postcode.

Ideally I want to modify the original list of User objects, and add the city name after it has been fetched in the second API call, but I'm stuck at figuring out how to do it.

Upvotes: 2

Views: 1166

Answers (2)

Aaron
Aaron

Reputation: 1009

Here is my understanding of your question. You have 2 API calls...

public Observable<List<User>> getUsers();
public Observable<String> getCityName(String postalCode);

And you want to set each user's city name based on the call to getCityName. You can convert the List into an observable stream by flatMapping it into an Observable from an Iterable. Here is one way to do that.

Observable<User> usersWithCity = getUsers()
        .flatMap(new Func1<List<User>, Observable<User>>() {
            @Override
            public Observable<User> call(List<User> users) {
                return Observable.from(users);
            }})
        .flatMap(new Func1<User, Observable<User>>() {
            @Override
            public Observable<User> call(User user) {
                return getCityName(user.getPostalCode())
                        .doOnNext(new Action1<String>() {
                            @Override
                            public void call(String t) {
                                user.setCityName(t);
                            }
                        })
                        .map(new Func1<String, User>() {
                            @Override
                            public User call(String cityName) {
                                return user;
                            }
                        });
            }
});

Note that this makes the assumption that there will only ever be one cityName for each postalCode.

Upvotes: 0

Reut Sharabani
Reut Sharabani

Reputation: 31339

This seems like a pretty straightforward observable:

Dummy API for users:

public static List<String> getUsers() {
    return new ArrayList<String>() {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        {
            add("Anakin");
            add("Darth");
        }
    };
}

Dummy API for city:

public static String getCity(String name) {
    // dummy ..
    return "Mos Espa";
}

Merging together:

public static void main(String[] args) throws InterruptedException {

    Observable.from(getUsers()).flatMap(
        // we have the user
        user -> Observable.just(getCity(user)).map(
            // we have the city
            city -> user + " from " + city)) // do stuff with user + city
        .subscribe(result -> System.out.println(result));
}

Upvotes: 2

Related Questions