compose-multiplatform icon indicating copy to clipboard operation
compose-multiplatform copied to clipboard

stringResource cache issue with formatArgs

Open StanKocken opened this issue 1 year ago • 1 comments

Describe the bug With the XML:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <string name="my_string">Hello %1$s</string>
</resources>

And val arg1 = "a", When using stringResource(Res.string.my_string, arg1), if arg1 changes from "a" to "b" in some conditions the returned string is still "Hello a".

Affected platforms

  • All

Versions

  • Kotlin version*: 1.9.22
  • Compose Multiplatform version*: 1.6.0-rc02
  • OS version(s)*: all

To Reproduce I cannot reproduce it on a simple project, but 100% on my current big one.

  • What I have a is a list of items, a data class that contains a String. I use this list data to create my stringResource.
  • When I display all the items: no problem, it works with stringResource taking into account the various params.
  • When I decide on a button click to hide some items, the remaining ones are not correct (not properly recompose), taking a cache version of the stringResource.

Expected behavior When calling stringResource(Res.string.my_string, arg1) it does return "Hello a" if arg1 = "a" and then stringResource(Res.string.my_string, arg1) it does return "Hello b" if arg1 = "b"

Screenshots Screenshot 2024-02-17 at 10 56 01

The variable a should return "Hello Alicia" (as param is "Alicia") but somehow it returns "Hello Jen & Ben" (as within a previous composition param was "Jen & Ben".

Additional context While looking at the code:

fun stringResource(resource: StringResource, vararg formatArgs: Any): String {
    val resourceReader = LocalResourceReader.current
    val args = formatArgs.map { it.toString() }
    val str by rememberResourceState(resource, { "" }) { env ->
        loadString(resource, args, resourceReader, env)
    }
    return str
}

The args is not part of the remember key. But that might be naive because it works in some cases… When it does not work it's when the method loadString is not called (because of the remember I assume).

Sorry if my explanation are not clear enough, happy to jump on a call if you want to see it by yourself.

StanKocken avatar Feb 17 '24 10:02 StanKocken

Thanks for an Issue!

dima-avdeev-jb avatar Feb 19 '24 10:02 dima-avdeev-jb