0

I have a use case that is as simple as this: Look for a Book in the Remote source, if it doesn't exist, create it. So this is my approach that used to work with rxJava1:

public void handleBook(int id) {
    getBookById(id) 
        .flatMap(new Func1<Book, Observable<Book>> {
            @Override
            public Observable<Book> call(Book book) {
                if(book != null) // it exists
                ...
                else // it's null - it doesn't exist ...
            }
        }
}


public Observable<Book> getBookById(int id) {
    Book book = remoteSource.book(id)
    return Observable.just(book)
}

In this case if the object book is null, the Observable.just call throws an exception. It's explicitly checking against null values. Back for rxJava 1 I could pass a null as value to Observable.just (or other accesoars), then in the map or flatMap operators I'd check if the value I get is null (meaning result does not exist) or not (meaning I got some result).

With this limitation it seems that I cannot do this check anymore. I tried returning Observable.empty() in case the book object is null but then the whole thread would complete and finish when the returned value is Observable.empty().

How can I check in a rx-chain of execution if something I need is there and branch the chain of execution afterwards?

2
  • Either use Single and check for errors or wrap the book object inside an Optional Commented Jul 10, 2017 at 12:13
  • can you tell me more about the first option? Using Single.. Commented Jul 10, 2017 at 12:21

1 Answer 1

1

Instead of using Observable<Book> as a return type use Single<Book>. Single type emits either an object or an error

NOTE: Right now I don't have an IDE so the code will probably have some compiler fails. I assume you'll fix it easily

public Single<Book> getBookById(int id) {
    return Single.create((e) => {
        Book book = remoteSource.book(id)
        if (book != null)
            e.emit(book);
        else
            e.fail();
    }
}

public void handleBook(int id) {
    getBookById(id) 
        .onErrorResume(e => createBook(...))
        ...
}

Like a said earlier I'm not sure about the exact code but you can read it as if it was pseudo-code

Sign up to request clarification or add additional context in comments.

3 Comments

Single.fromCallable would be better than Single.create
why this does it have to do with Single ? Observable can be solution for this also. But, the problem here is that "onErrorResumeNext" would execute anyway, whether there's an error or not. So it's not applicable as a solution :-/
As far as I know the body of onErrorResumeNext is only executed if an exception was thrown. Which is what happens if the book fetched is null. Single is more appropiate for this than Observable since Observable is a flow of 0..N items and Single is just the item or error. And that is the scenario you have here: a book or error. You also have Maybe (1 item or none) but I don't actually remember how to operate if none was emitted

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.