Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trackClick implementation for Composable onClick functions that take parameters #1409

Open
socksinbed opened this issue May 2, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@socksinbed
Copy link

Is your feature request related to a problem? Please describe.
In the Compose SDK, com.datadog.android.compose.trackClick cannot be used for Composables that take an onClick with parameters, such as ClickableText which has a function signature:

@Composable
fun ClickableText(
    ...
    onClick: (Int) -> Unit
)

If we try to use it, there's a type mismatch:

@Composable
fun ClickableTextWithTrackedClicks(
    onClick: (Int) -> Unit
) {
    ClickableText(
        ...
        onClick = trackClick(targetName = "Test") { TODO() } // Type mismatch here, as (Int) -> Unit is expected
    )
}

Because trackClick is also a @Composable, it doesn't seem like there's a way to wrap it in a lambda.
eg. If we wished to print the Int parameter

    ClickableText(
        ... 
        onClick = { i: Int ->
            println(i)
            trackClick(targetName = "Test") {}.invoke() // Can't be invoked because we're not in a `Composable` context
        }
    )

Describe the solution you'd like
An implementation of trackClick that accepts a generically typed onClick lambda parameter such as:

@Composable
fun <T> trackClick(
    targetName: String,
    onClick: (T) -> Unit
): (T) -> Unit {
    val onTapState = rememberUpdatedState(newValue = onClick)
    return remember(targetName, attributes) {
        TapActionTracker(targetName, attributes, onTapState)
    }
}

// This will require a separate mplementation of TapActionTracker as well
internal class TapActionTracker<T>(
    private val targetName: String,
    private val attributes: Map<String, Any?> = emptyMap(),
    private val onTap: State<(T) -> Unit>,
    private val rumMonitor: RumMonitor = GlobalRum.get()
) : (T) -> Unit {

    override fun invoke(param: T) {
        // RUM code
        onTap.value.invoke(arg)
    }
}
@socksinbed socksinbed added the enhancement New feature or request label May 2, 2023
@0xnm
Copy link
Contributor

0xnm commented May 3, 2023

Hello @socksinbed! Thanks for reporting the issue, we will try to improve this API indeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants