1

I'm using the ReactiveKit's Bond library in my project for the first time and trying to get the hang of it.

In my app, there's a textview. And as the user types in it, an API call needs to fire at three stages.

  1. As soon as the first character is typed.
  2. After that each 8 seconds.
  3. Finally one time after 10 seconds has passed since the user typed the last character.

I'm trying to see if I can accomplish this.

textView.reactive.text
    .map { $0!.characters.count > 0 }
    .throttle(seconds: 8)
    .observeNext { _ in
        print("-> Call API")
    }

I'm encountering an issue here too. Even though I have the character count validation added, as soon as this code is executed, the Call API gets printed to the console. Without the keyboard even becoming the first responder of the textview.

The method firing in 8 second intervals part works fine. Again I couldn't find a way to implement the third scenario.

Any help is appreciated.

Isuru
  • 30,617
  • 60
  • 187
  • 303

1 Answers1

1

To solve the first issue, you need to filter empty strings, not map them to a boolean.

You've got the throttling correctly. That gives you at most one event per 8 second interval.

Now, to fire an event only if it's not followed by another event within 10 seconds, you'll need to use debounce operator.

Finally, you'll do the API call on either of these two events, so you'll have to merge your signals in order to receive both events.

Here is a verbose code, you should probably make it compact though :)

let text = textView.reactive.text.ignoreNil()
let textEntered = text.filter { !$0.isEmpty }
let atMostOncePer8Seconds = textEntered.throttle(seconds: 8)
let on10SecondsAfterFinalEntry = textEntered.debounce(interval: 10)
let doTheCall = merge(atMostOncePer8Seconds, on10SecondsAfterFinalEntry)

doTheCall.observeNext { text in
    print("-> Call API", text)
}
Srđan Rašić
  • 1,597
  • 15
  • 23
  • Thanks so much for the answer. I couldn't find a top level `merge` function though. I have Bond v6.0.1 installed. Does this `atMostOncePer8Seconds.merge(with: on10SecondsAfterFinalEntry)` work? – Isuru Feb 14 '17 at 15:19
  • Yes, it's the same. I think you might need to `import ReactiveKit` in order to get it. – Srđan Rašić Feb 15 '17 at 13:09
  • Oh okay, thanks. btw I had to do one change in your code. I had to call the `debounce` function on `textEntered`, not `text`. Otherwise the API call would still fire even before the textview is activated. – Isuru Feb 15 '17 at 13:11