Skip to content Skip to sidebar Skip to footer

How Can Multiple Requests Used To Populate Models Be Handled Using Rxjava Observables?

We are using ReactiveX and Retrofit in our network stack to handle all API requests in an asynchronous way. Our goal is to create one method that will return a completely populate

Solution 1:

I wrote a small sample app that makes what you are trying to achieve. Here the components:

publicclassDatasource {

    publicObservable<List<User>> users() {
        returnObservable.just(Arrays.asList(
                newUser("1", "Foo"), newUser("2", "Bar")
        ));
    }

    publicObservable<List<Pet>> pets(User user) {
        returnObservable.just(Arrays.asList(
                newPet(user.getName() + "'s cat"),
                newPet(user.getName() + "'s dog")
        ));
    }
}

Pet class:

publicclassPet {
    privateString mName;

    publicPet(String name) {
        mName = name;
    }

    publicStringgetName() {
        return mName;
    }

    @OverridepublicStringtoString() {
        return"Pet{" +
                "mName='" + mName + '\'' +
                '}';
    }
}

User class:

publicclassUser {

    privateString mName;
    privateString mId;
    privateList<Pet> mPetList;

    publicUser(String id, String name) {
        this(id, name, Collections.<Pet>emptyList());
    }

    publicUser(String id, String name, List<Pet> pets) {
        mName = name;
        mId = id;
        mPetList = pets;
    }

    publicStringgetName() {
        return mName;
    }

    publicStringgetId() {
        return mId;
    }

    publicUsercopyWithPets(List<Pet> pets) {
        returnnewUser(mId, mName, pets);
    }

    @OverridepublicStringtoString() {
        return"User{" +
                "mName='" + mName + '\'' +
                ", mId='" + mId + '\'' +
                ", mPetList=" + mPetList +
                '}';
    }
}

Put all together:

datasource.users()
        .flatMap(new Func1<List<User>, Observable<User>>() {
            @OverridepublicObservable<User> call(List<User> users) {
                returnObservable.from(users);
            }
        })
        .flatMap(new Func1<User, Observable<User>>() {
            @OverridepublicObservable<User> call(finalUser user) {
                return datasource.pets(user)
                        .map(new Func1<List<Pet>, User>() {
                            @OverridepublicUser call(List<Pet> pets) {
                                return user.copyWithPets(pets);
                            }
                        });
            }
        })
        .toList()
        .subscribe(new Action1<List<User>>() {
            @Overridepublic void call(List<User> users) {
                for (User user : users) {
                    Log.d(TAG, "user: "+ user.toString());
                }
            }
        });

It produces:

D/MainActivity: user: User{mName='Foo', mId='1', mPetList=[Pet{mName='Foo's cat'}, Pet{mName='Foo's dog'}]}
D/MainActivity: user: User{mName='Bar', mId='2', mPetList=[Pet{mName='Bar's cat'}, Pet{mName='Bar's dog'}]}

If it doesn't answer you question please post you actual datamodel for User and Pet.

Post a Comment for "How Can Multiple Requests Used To Populate Models Be Handled Using Rxjava Observables?"