I'm looking at ways to specify a modifier conditio...
# compose
c
I'm looking at ways to specify a modifier conditionally. I found two samples in this slack. 1.
Copy code
inline fun Modifier.modifyIf(condition: Boolean, then: Modifier.() -> Modifier): Modifier =
    if (condition) then() else this
2.
Copy code
inline fun Modifier.thenIf(condition: Boolean, block: () -> Modifier) =
    this.then(if (condition) block() else Modifier)
Number 1 does not work for me (it actually messed up my modifier), while number 2 works exactly as expected. I'm not sure why. Any ideas?
Copy code
Box(
    modifier =
        Modifier
            .fillMaxSize()
            .aspectRatio(240 / 360f)
            .modifyIf(cardClick != null) { Modifier.clickable { cardClick!!() } }
)
the above somehow messes with my box size. That's option 1.
Copy code
Box(
    modifier =
        Modifier
            .fillMaxSize()
            .aspectRatio(240 / 360f)
            .thenIf(cardClick != null) { Modifier.clickable { cardClick!!() } }
)
while option 2, works perfect!
i
Your else statement in the first one just throws away
this
, instead of building upon it by using
then
(which is all the fluent style is actually doing under the hood), so yeah, anything before your
modifyIf
is going to be dropped
👍 1
1
b
@Ian Lake That's not exactly right,
this
is used implicitly, it's not thrown away, and you don't need to use
then
in the first version.
It's not the
else
statement that's the issue, it's your callback; you're using
Modifier
instead of
this
.
Simply leave out the
Modifier
call and
this
will be used automatically:
Copy code
Box(
    modifier =
        Modifier
            .fillMaxSize()
            .aspectRatio(240 / 360f)
            .modifyIf(cardClick != null) { clickable { cardClick!!() } }
)
👍 1
s
This is not used implicitly actually, Ian is right. Even though
then
is an extension on Modifier and is called with
this
context, inside the lambda a completely new Modifier is created and the one passed inside the lambda is dropped. For it to work it would have to be something like: (not sure if this compiles but you get the idea I hope)
Copy code
.modifyIf(cardClick != null) { this.then(Modifier.clickable { cardClick!!() }) }
b
@Stylianos Gakis You're still referencing Modifier for no reason. The existing one is passed in to the lambda, you can call clickable directly (since
this
is
Modifier
), like in my example above. Yours works too, but there's no reason to call
then
in this example. You can leave out
this.
in your code as well.
s
Oh yeah sure, but I was just referring how the snippet that was sent before was in fact not working. But yeah you are right, from that snippet, if you just removed the
Modifier.
part it should work. But I personally wouldn’t really like how this looks like, as someone who had never seen that function before the lack of explicitness would make me have to look at the source code to understand it. But again, this is a personal opinion 😅