Mohammed Riyadh
Mohammed Riyadh

Reputation: 1019

RxSwift With UiTextField

Im new to RxSwift and what Im trying is perform the following,

I tried the below code as example

class DestinationSearch: UIViewController {
    

    let searchTF = UITextField()    
    var disposeBag = DisposeBag()


    override func viewDidLoad() {
        super.viewDidLoad()

        setUpUI()
        
        
        searchTF.rx.controlEvent(.editingChanged)
            .throttle(.milliseconds(1000), scheduler: MainScheduler.instance)
            .withLatestFrom(searchTF.rx.text)
        .subscribe(onNext:{ query in
            print(self.hitSomeApi(query: query ?? "--"))
        }).disposed(by: disposeBag)

    }

func hitSomeApi(query: String) -> String {
        return query + " Response from API"
    }

When I run the app and start typing I get the the Response from API message with each letter or backspace button pressed! why the throttle delay is not working? Im I doing something wrong here?

Any help will be much appreciated

Upvotes: 1

Views: 1291

Answers (1)

Sweeper
Sweeper

Reputation: 272715

Based on your description of the problem, it seems like the debounce operator is more suitable than throttle. debounce only emits an element if a certain time, in which nothing has been emitted, has passed, whereas throttle ensures that elements are emitted at least a certain time interval apart.

I can confirm that your code using throttle is working as I'd expect - if I type very quickly, the "Response from API" messages appear roughly every 1 second. If I type very slowly, slower than 1 keystroke per second, then the messages come whenever I press a key. In other words, whenever there is an editing changed event, throttle checks to see if there was a previous one less than 1 second ago. If there is, ignore this new one.

If you use debounce however (the same code, just replace throttle with debounce), then after each keystroke, it would wait for 1 second to see if the text field is going to change again. It would only emit the editing changed event if it has waited and there is no more editing changed events. So if you keep typing at a pace higher than 1 keystroke per second, no elements will ever be emitted by the observable. This seems to be what you want.

You can compare these two operators on RxMarbles (they are called slightly different names there):

Upvotes: 3

Related Questions