Is Observable<Void> considered best practice?

15,209 views
Skip to first unread message

Tony Piazza

unread,
Apr 13, 2015, 8:46:11 PM4/13/15
to rxj...@googlegroups.com
I have a CRUD repository that I am rewriting with RxJava so that the methods return some form of Observable. The only method I am not sure about is this one:

Observable<Void> delete(T entity)

I am wondering if this type of method definition is considered best practice. If not, please let me know if there is a better way to define a method that is asynchronous but does not return anything. Here is my current code for unit testing that method:

repository
   .delete(entity)
   .timeout(1, TimeUnit.SECONDS)
   .toBlocking()
   .singleOrDefault(null);


All that I need to test for is that the onCompleted method is invoked on the subscriber. Using singleOrDefault seems like an easier way to accomplish this. Please let me know if there is a more appropriate way to use/test this method.

Thanks in advance for your help.

Ben Christensen

unread,
Apr 13, 2015, 8:49:19 PM4/13/15
to Tony Piazza, rxj...@googlegroups.com
That is the approach I have been taking for async events only needing terminal onComplete/onError.

Ben Christensen
310.782.5511
@benjchristensen

Tony Piazza

unread,
Apr 13, 2015, 8:56:15 PM4/13/15
to rxj...@googlegroups.com
Thanks for your fast reply! Any thoughts on my second question about the client code? This code is part of a developer course I am writing and I want to demonstrate best practice as much as possible.

Jake Wharton

unread,
Apr 17, 2015, 2:53:20 PM4/17/15
to rxj...@googlegroups.com
What about when you want to switch an Observable<T> into an Observable<Void>? There's ignoreElements() which gives behavior but retains the T in the type system.

Ben Christensen

unread,
Apr 28, 2015, 1:41:09 AM4/28/15
to Jake Wharton, rxj...@googlegroups.com
I don’t have any particularly good answer for that one other than using the cast() operator for changing types (or an awkward map() function) and/or filter().cast() or filter().map(). 



Sent from Mailbox

Ben Christensen

unread,
Apr 28, 2015, 1:44:33 AM4/28/15
to Tony Piazza, rxj...@googlegroups.com
For the second question, the singleOrDefault or default approach seems appropriate to me. 

Another approach is to use toList().toBlocking().single(). That does involve allocating a List though which singleOrDefault does not. 


Sent from Mailbox

Tony Piazza

unread,
Jul 6, 2015, 3:24:13 PM7/6/15
to rxj...@googlegroups.com
Jake,

Did you ever come up with a solution to switching an Observable<T> into an Observable<Void> ?

-Tony

Tony Piazza

unread,
Jul 6, 2015, 3:43:38 PM7/6/15
to rxj...@googlegroups.com
I was thinking about using the compose method as follows to solve the problem raised by Jake:

asyncBucket

  .remove(doc)   // emits Observable<JsonDocument>

  .compose(new Transformer<JsonDocument, Void>() {

    @Override

    public Observable<Void> call(Observable<JsonDocument> doc) {

      return null;

    }

});


Thoughts?

Tony Piazza

unread,
Jul 6, 2015, 4:36:12 PM7/6/15
to rxj...@googlegroups.com
Correction:

asyncBucket

  .remove(doc)   // emits Observable<JsonDocument>

  .compose(new Transformer<JsonDocument, Void>() {

    @Override

    public Observable<Void> call(Observable<JsonDocument> doc) {

      return Observable.empty();

    }

});

Jake Wharton

unread,
Jul 7, 2015, 1:45:49 PM7/7/15
to rxj...@googlegroups.com
Nothing beyond ignoreElements().cast(Void.class). I ended up changing approaches and not needing to do this anymore though.

Ben Christensen

unread,
Jul 14, 2015, 12:21:58 PM7/14/15
to Jake Wharton, rxj...@googlegroups.com
There is a discussion in https://github.com/ReactiveX/RxJava/issues/3037 that is trying to address use of Observable<Void> that you may want to weigh in on.
Reply all
Reply to author
Forward
0 new messages