Search code examples
androidkotlinrx-java2

Preventing rapid clicks on a button and making a request using rxjava


I have the following method that makes a request to get a pokemon from a endpoint.

I would like to prevent the user in making rapid requests by clicking quickly on the button that will invoke this method many times. I have used the throttle* methods and debounce.

Bascially, what I am looking for if the user rapidly clicks on the button within 300 milliseconds duration it should accept the last click in that duration. However, what i am experiencing is that all requests are being made. i.e. if the user rapidly clicks 3x within that duration I still get 3 requests.

   fun getPokemonDetailByName(name: String) {
        pokemonDetailInteractor.getPokemonDetailByName(name)
            .subscribeOn(pokemonSchedulers.background())
            .observeOn(pokemonSchedulers.ui())
            .toObservable()
            .throttleFirst(300, TimeUnit.MILLISECONDS)
            .singleOrError()
            .subscribeBy(
                onSuccess = { pokemon ->
                    pokemonDetailLiveData.value = pokemon
                },
                onError = {
                    Timber.e(TAG, it.localizedMessage)
                }
            ).addTo(compositeDisposable)
    }

Solution

  • Thanks for all the answers.

    However, I found a solution that works using RxBinding with debounce operator. I'm posting here as it could be useful to someone else.

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PokemonViewHolder {
        binding = PokemonListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        val pokemonViewHolder = PokemonViewHolder(binding.root)
    
        pokemonViewHolder.itemView.clicks()
            .debounce(300, TimeUnit.MILLISECONDS)
            .subscribeBy(
                onNext = {
                    val name = pokemonList[pokemonViewHolder.adapterPosition].name
    
                    if(::pokemonTapped.isInitialized) {
                        pokemonTapped(name)
                    }
                },
                onError = { Timber.e(it, "Failed to send pokemon request %s", it.localizedMessage) }
            ).addTo(compositeDisposable)
    
        return pokemonViewHolder
    }