Reputation: 1035
Pretty new to project reactor here, I am struggling to put a conditional check inside my Mono stream. This part of my application is receiving an object from Kafka. Let's say the object is like this.
data class SomeEvent(val id: String, val type: String)
I have a function that handles this object like this.
fun process(someEvent: SomeEvent): Mono<String> {
val id = someEvent.id
val checkCondition = someEvent.type == "thisType"
return repoOne.getItem(id)
.map {item ->
// WHAT DO I DO HERE TO PUT A CONDITIONAL CHECK
createEntryForItem(item)
}
.flatMap {entry ->
apiService.sendEntry(entry)
}
.flatMap {
it.bodyToMono(String::class.java)
}
.flatMap {body ->
Mono.just(body)
}
}
So, what I want to do is check whether checkCondition
is true
and if it is, I want to call a function repoTwo.getDetails(id)
that returns a Mono<Details>
.
createEntryForItem
returns an object of type Entry
apiService.sendEntry(entry)
returns a Mono<ClientResponse>
It'd be something like this (in my mind).
fun process(someEvent: SomeEvent): Mono<String> {
val id = someEvent.id
val checkCondition = someEvent.type == "thisType"
return repoOne.getItem(id)
.map {item ->
if (checkCondition) {
repoTwo.getDetails(id).map {details ->
createEntryForItem(item, details)
}
} else {
createEntryForItem(item)
}
}
.flatMap {entry ->
apiService.sendEntry(entry)
}
.flatMap {
it.bodyToMono(String::class.java)
}
.flatMap {body ->
Mono.just(body)
}
}
But, obviously, this does not work because the expression inside the if statement
is cast to Any
.
How should I write it to achieve what I want to achieve?
UPDATED: The location of where I like to have the conditional check.
Upvotes: 1
Views: 2443
Reputation: 336
You should use flatMap()
and not map()
after getItem()
.
return repoOne.getItem(id)
.flatMap {item ->
if (checkCondition) {
repoTwo.getDetails(id).map {details ->
createEntryForItem(item, details)
}
} else {
Mono.just(createEntryForItem(item))
}
}
In a map{}
you can transform the value. Because you want to call getDetails()
(which returns a reactive type and not a value) to do that you have to use flatMap{}
. And that's why you need to wrap your item in a Mono
by calling Mono.just(createEntryForItem(item))
on the else branch.
Upvotes: 1
Reputation: 4554
Just split it to another function. Your code will be cleaner too.
repoOne.getItem(id)
.map { createEntry(it, checkCondition) }.
.flatMap.....
private fun createEntry(item, checkCondition): Item {
return if (checkCondition) {
repoTwo.getDetails(id).map { createEntryForItem(item, it) }
} else {
createEntryForItem(item)
}
}
Upvotes: 0