46

I would need an Observable, for example to provide a system clock, which does not need to pass anything in onNext(). I couldn't find a signature that would allow me to do that.

Sure, I could use any object and then pass null, but that doesn't make much sense. So my question is if there is a better way to do that.

Observable.create(new Observable.OnSubscribe<Anyobject>() { // use any object in the signature

            @Override public void call(Subscriber<? super Anyobject> subscriber) {

                    subscriber.onNext(null); // then pass null
                    subscriber.onCompleted();

            }

        })
bric3
  • 40,072
  • 9
  • 91
  • 111
Oliver Hausler
  • 4,900
  • 4
  • 35
  • 70
  • So you just want to call onNext() without any arguments? – david.mihola Oct 01 '14 at 17:09
  • 2
    Note for others coming here, `onNext(null)` is not ok despite what other answers and comments say. See [the spec](https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.0/README.md#2-subscriber-code). Also see [this issue](https://github.com/ReactiveX/RxJava/issues/4644) in RxJava. – Chad Retz Nov 09 '16 at 00:21

6 Answers6

46

You don't need to call onNext if your Observable doesn't emit anything. You could use Void in your signature and do something like

Observable<Void> o = Observable.create(new Observable.OnSubscribe<Void>() {
    @Override
    public void call(Subscriber<? super Void> subscriber) {
        // Do the work and call onCompleted when you done,
        // no need to call onNext if you have nothing to emit
        subscriber.onCompleted();
    }
});

o.subscribe(new OnCompletedObserver<Void>() {
    @Override
    public void onCompleted() {
        System.out.println("onCompleted");
    }

    @Override
    public void onError(Throwable e) {
        System.out.println("onError " + e.getMessage());
    }
});

You can define an OnCompletedObserver to simplify your Observer callback so that you don't have to override the onNext since you don't need it.

public abstract class OnCompletedObserver<T> implements Observer<T> {
    @Override
    public void onNext(T o) {

    }
}

If I've understood what you're asking then this should do the trick.

Miguel
  • 19,793
  • 8
  • 56
  • 46
  • 1
    I want my Observable to emit something, which is the regular tick, even though this tick does not carry anything else than the moment in time (which doesn't require an object to be passed). The trick with using Void is nice, but I guess I can't pass void in onNext(void) as Void cannot be instantiated. I can pass null, though, so it does the job fine. Thanks! – Oliver Hausler Oct 01 '14 at 19:02
  • Yes you're correct you can simply use `null` in that case. – Miguel Oct 01 '14 at 19:40
  • @MiguelLavigne can you kindly update your answer? I know it works fine but given the recent API update(s) maybe we can implement this in different but more elegant ways? Thanks! – beerBear Oct 31 '16 at 03:52
  • 1
    @beerBear agreed this answer those need revising, I will be doing this shorty, thank you! – Miguel Nov 01 '16 at 01:50
  • 6
    `null` is no longer allowed in RxJava 2 – BoD Oct 18 '17 at 15:29
43

If you need something to be passed to onNext() before onCompleted() is called:

Observable.<Void>just(null)

If you only need onCompleted() to be called:

Observable.empty()
Mike Strobel
  • 25,075
  • 57
  • 69
  • A lot of methods in legacy code base were using `Observable` as return type. In case no action was needed, passing `Observable.empty()` seemed like a valid choice. But I was facing issues as in few situations `Observable.empty()` would cause return type mismatch (`Observable>` instead of `Observable`). This answer of yours was very helpful, as I was able to do `Observable.empty()` without making any other fuss. Thank you. – Saurabh Shrivastava Nov 20 '19 at 03:13
13

RxJava 2 Wiki:

RxJava 2.x no longer accepts null values and the following will yield NullPointerException immediately or as a signal to downstream.

...

This means that Observable<Void> can no longer emit any values but only terminate normally or with an exception. API designers may instead choose to define Observable<Object> with no guarantee on what Object will be (which should be irrelevant anyway)

It means that you can't use Void and do Observable.just(null).

Use Object or some other simple type instead:

Observable.just(new Object());
mixel
  • 25,177
  • 13
  • 126
  • 165
3

One of the light solutions is to use Observable<Boolean>

And then onNext(Boolean.TRUE) which you then just ignore.

But probably you shouldn't use Observable in that case.
Consider using Completable instead

Leo DroidCoder
  • 14,527
  • 4
  • 62
  • 54
3

Starting with RxJava 2, the propper way to do this is to use a Completable

From the docs:

Represents a deferred computation without any value but only indication for completion or exception. The class follows a similar event pattern as Reactive-Streams: onSubscribe (onError|onComplete)?

AllDayAmazing
  • 2,383
  • 1
  • 24
  • 25
0

I don't know this will helps you or not.
The code written in RxSwift.

// Create an observable and emit somethings
let myObservable = Observable<Void>.create{ observer in
    observer.on(.next(Void()))
    return Disposables.create()
}

// Observer subscribe changes
myObservable.subscribe(onNext: {
    _ in
    print("Hello")
}).disposed(by: disposeBag)

Or use the Variable object

// Create a Variable object that contanins nothing
var myValueWatcher:Variable<Void> = Variable<Void>(Void())

// Observer subscribe changes
myValueWatcher.asObservable().skip(1).subscribe(onNext: {
    _ in
    print("Changes!")
}).disposed(by: disposeBag)


// The emit code
myValueWatcher.value = Void()
Johnny
  • 1,824
  • 23
  • 16