Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you show spinner if RxJava observable takes to long?

I feel like someone has to have tried this, but I can't figure out a nice way to do something if an observable takes to long.

This is the flow I want.

Start a search.
If the search takes longer than some time,
    show a spinner or show progress bar.
When finished do subscription action and hide spinner/progress bar.

The closest I can think of is like a Zip

manager.search(searchTerm)
       .zip(Observable.Timer(1, TimeUnit.SECONDS))
       .subscribe(
           // if the search is non null then we are good
           // if the long time is non 0 we need to show spinner
       );

Is there something better to do? I have been trying all day with no success. In a perfect world I feel like I would want something like

manager.search(searchTerm)
       .timeout(i -> /* do timeout stuff */, 1, TimeUnit.SECONDS)
       .subscribe(item -> /* do search result stuff */);
like image 313
David Stocking Avatar asked Dec 17 '15 04:12

David Stocking


People also ask

How do I stop Observable RxJava?

using() and subscribe to the Observable with a Subscriber so you can call subscriber. unsubscribe() when the user clicks the button to cancel. Here's an outline. This will stop the observable stream and call socketDisposer() to stop the network activity.

What is onNext in RxJava?

onNext(): This method is called when a new item is emitted from the Observable. onError(): This method is called when an error occurs and the emission of data is not successfully completed. onComplete(): This method is called when the Observable has successfully completed emitting all items.

Can we create our own Observable in RxJava?

just() This is one of the easiest and convenient ways to create observable. just() constructs a reactive type by taking a pre-existing object and emitting that specific object to the downstream consumer upon subscription. The just operator converts an item into an Observable that emits that item.


1 Answers

Today i found a bit odd but working solution. Idea is to use interval instead of timer.

    fun <T> base_delayed_progress_observable(source: Observable<T>): Observable<T>
    {
        val timer = Observable.interval(100, TimeUnit.MILLISECONDS) //Creates observable that will emit Long++ each 100 miliseconds
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(
                    {
                        if (it == 10L)//Here we check current timer value. For example here i check if it is 1 second gone (100 miliseconds * 10 = 1 second)
                        {
                            //here we put all we need to show progress/spinner an so on
                        }
                    })

        return Observable.zip(source, timer,
            BiFunction<T, Long, T> { t1, t2 ->
                //Here we return our original Obervable zipped with timer
                //Timer will be cancelled when our source Observable gets to OnComplete
                return@BiFunction t1
            }).doFinally(
            {
                //Here we can dismiss all progress dilogs/spinner
            })
    }
like image 112
Bios90 Avatar answered Sep 19 '22 20:09

Bios90