0

I have a rxJava2 Observable to which I want to subscribe conditionally. The scenario i will make a network call and the subscribe() is called only when the device is connected to network.I want to do something like below

     observable. 
     subsribeWhenConditionIsMet(

   if (connected to internet) {
      mPresentation.showNetworkError();
      return;
    }

   subscribe();
  }
)

Any suggestions on how to do this? Any better approaches available?

Nari
  • 333
  • 5
  • 13
  • use `flatMap`. Add your condition in `flatMap`, if not connected to the internet then return your `showNetworkError` observable else return `observable.just(false)` – Niraj Chauhan Mar 05 '19 at 11:03

2 Answers2

2

For now there is no such method is available in RxJava2. But if you are using kotlin you can do it using extension function. Declare it like below.

fun <T> Observable<T>.subscribeIf(predicate: () -> Boolean) {
    if (predicate()) {
        subscribe()
    }
}

At the time of call :

anyObservable()
    .subscribeIf { isConnectedToInternet() }

Extra

In case if you want to handle fallback situation you can write your extension like below and make fallback lambda optional so that we can omit it if not required.

fun <T> Observable<T>.subscribeIf(predicate: () -> Boolean, fallback: () -> Unit = {}) {
    if (predicate()) {
        subscribe()
    } else {
        fallback()
    }
}

At the time of call:

anyObservable()
    .subscribeIf(
        predicate = { isConnectedToInternet() },
        fallback = { showError() }
    )
}

Note: You can also call it from Java, refer this link https://stackoverflow.com/a/28364983/3544839

Moinkhan
  • 12,732
  • 5
  • 48
  • 65
0

Having internet access is more than a simple condition, if you think about it it's more like a stream of booleans, sometimes it's true, sometimes it's false.

What you want is to create an Observable that fires true when an internet connection becomes available. If you're on Android, you can have a BehaviourSubject in a broadcast receiver

public class NetworkChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        final ConnectivityManager connMgr = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        final android.net.NetworkInfo wifi = connMgr
                .getNetworkInfo(ConnectivityManager.TYPE_WIFI);

        final android.net.NetworkInfo mobile = connMgr
                .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

        boolean hasInternet = wifi.isAvailable() || mobile.isAvailable()
        subject.onNext(hasInternet);
    }
}

You still need to somehow pass the subject to your broadcast receiver but it shouldn't be a big deal.

Then, in order to subscribe to your observable only when this subject returns true, you can do it like so:

 subject
                .filter(hasInternet ->
                        hasInternet // Don't continue if hasInternet is false
                )
                .flatMap(o ->
                        yourObservable // At this point, return the observable cause we have internet
                )
                .subscribe() // subscribe
Benoit TH
  • 601
  • 3
  • 12