Reputation: 2595
I am struggling with rx-java2. Basically, I cannot safely "escape" from Maybe
to Single
and continue the logic flow for the rest items.
So here's my simplified code, demonstrating my question:
public Flowable<Long> run() {
//let's assume this is my "input" data
List<UserTask> userTasks;
return Single.just(userTasks)
.flatMapPublisher(Flowable::fromIterable)
// userRepository.getUser returns a Maybe<User>
.map((UserTask ut) -> userRepository.getUser(ut.getName())
//search for user
//if not found, return a dummy user object
.defaultIfEmpty(User.newBuilder().build())
//leave dummy user objects only
.filter((User u) -> u.getName() == null)
//for each dummy user object return a corresponding user task
.map(u -> ut)
)
.flatMapSingle(Maybe::toSingle)
.flatMap((UserTask mt) -> {
// return user related to user task, implementation does not matter
return Flowable.just(User.newBuilder().build());
})
.flatMapSingle(this::saveUser);
}
private Single<Long> saveUser(User u) {
return userRepository.saveUser(m).subscribeOn(Schedulers.io());
}
I tried to provide types where needed to ease the understanding.
The problem here is that in case the Maybe
is empty, this line (I guess) .flatMapSingle(Maybe::toSingle)
throws an exception NoSuchItemException
and the flow execution terminates. Is it possible to improve my code so that if Maybe
value is absent, the flow skips this item and goes on?
Please let me know if there's some missing details, I'll provide them.
Upvotes: 1
Views: 1385
Reputation: 69997
Not sure why you chose this convoluted set of operators. Try this:
public Flowable<Long> run() {
//let's assume this is my "input" data
List<UserTask> userTasks;
return
Flowable.fromIterable(userTasks)
// userRepository.getUser returns a Maybe<User>
.flatMapMaybe((UserTask ut) -> userRepository.getUser(ut.getName())
.defaultIfEmpty(User.newBuilder().build())
.filter((User u) -> u.getName() == null)
.map(u -> ut)
)
.map((UserTask mt) -> {
// return user related to user task, implementation does not matter
return User.newBuilder().build();
})
.flatMapSingle(this::saveUser);
}
private Single<Long> saveUser(User u) {
return userRepository.saveUser(m).subscribeOn(Schedulers.io());
}
The documentation details the type conversions between reactive types.
Upvotes: 4