ursus
05/19/2023, 12:09 PMfun msisdnType(msisdn: String) {
setState { copy(msisdnValid = PENDING)}
scope.launch {
val isValid = validator.validate(msisdn) <~~~~~~~~~~~~~
setState { copy(msisdnValid = if (isValid) VALID else INVALID)}
}
}
i.e. I want the validation to ne debounced
yes im aware it should probably be a flow, just curious as how would one do thatephemient
05/19/2023, 12:19 PMursus
05/19/2023, 12:19 PMursus
05/19/2023, 12:20 PMCasey Brooks
05/19/2023, 2:24 PMChannel
and consuming them as a Flow, so you can process the requests one-by-one and apply the logic that way. Passing the requests through a Channel gives you a lot of flexibility in dealing with this kind of logic properly.
private val validationChannel = Channel<String>()
private fun processValidation() {
validationChannel
.consumeAsFlow()
// I think this is the right operator for what you want, but you may need to play around with it to get it working
.buffer(capacity = Channel.RENDEZVOUS, onBufferOverflow = BufferOverflow.DROP_OLDEST)
.map {
val isValid = validator.validate(it)
setState { copy(msisdnValid = if (isValid) VALID else INVALID) }
}
.launchIn(scope)
}
public fun msisdnType(msisdn: String) {
setState { copy(msisdnValid = PENDING) }
validationChannel.trySend(msisdn)
}
Or alternatively, in this case you can hold onto the Job
returned by scope.launch
and check to see if it’s still active, and skipping the launch if so.
private var job: Job? = null
public fun msisdnType(msisdn: String) {
setState { copy(msisdnValid = PENDING) }
if(job?.isActive == true) {
// there's a job already running, ignore the request
} else {
job = scope.launch {
val isValid = validator.validate(msisdn)
setState { copy(msisdnValid = if (isValid) VALID else INVALID)}
}
}
}
Casey Brooks
05/19/2023, 2:26 PMmsisdnType()
is called from multiple threads, there may be race conditions with settings/checking the job.