renderIf

open fun <V> Flow<V>.renderIf(predicate: (V) -> Boolean, into: Tag<HTMLElement>? = null, content: Tag<*>.(V) -> Unit)

Renders the data of a Flow only if the given predicate is true.

Example:

data class Delivery(
val state: String,
val isVisible: Boolean
)

val storedDelivery = storeOf(Delivery("in production", true))

storedDelivery.data.renderIf(Delivery::isVisible) { delivery ->
// This whole block might be re-rendered if the state is changed! (read on)
p { +"The state of your delivery is ${delivery.state}" }
}

Beware that the data value V and its changes are still handled reactively inside the content expression!

So while the predicate may remain stably true, some other aspect of the model V may change in between. As a result, the whole content-block would be re-rendered accordingly of course!

Example:

val storedDelivery = object : Store<Delivery> by storeOf(Delivery("in production", true)) {
val proceed = handle<String> { delivery, newState ->
// we dont change the visibility, so the condition will remain the same, while the state changes!
delivery.copy(state = newState)
}
}

button {
+"Proceed to conveyed"
clicks.map { "conveyed" } handledBy storedDelivery.proceed
}

storedDelivery.data.renderIf(Delivery::isVisible) { delivery ->
// This whole block will re re-rendered on button click above!
p { +"The state of your delivery is ${delivery.state}" }
}

If you want the content to only change once if the condition changes (i.e. switches from true to false or back) you need to rely on an appropriate Flow-function like distinctUntilChangedBy

Example:

storedDelivery.data.distinctUntilChangedBy(Delivery::isVisible).renderIf(Delivery::isVisible) { delivery ->
// This wont be re-rendered if `Delivery.state` changes!
// The whole block will disappear on `Delivery.isVisible` changes to `false`,
// and appear again on `Delivery.isVisible == true`. Then with the current `state` at that moment of course!
p { +"The state of your delivery is ${delivery.state}" }
}

But in most cases, that is not what you really want! Strive for solutions, where the UI portions really adopt reactively. The above is a strange hybrid case, where not all state changes are reflected by the UI.

Receiver

Flow containing the data

Parameters

predicate

must be true for the value to be rendered

into

target to mount content to. If not set a child div is added to the Tag this method is called on

content

RenderContext for rendering the data to the DOM

See also