https://kotlinlang.org logo
Title
a

Ayfri

12/12/2021, 3:53 PM
Hi, is there a way to observe a MutableState value ? Like executing a code when the value is changed
s

SrSouza

12/12/2021, 3:54 PM
You mean outside of a composition?
a

Adam Powell

12/12/2021, 3:54 PM
yes, there are ways to do it, that's how composition and compose-ui do it. 🙂 the best way to do it will depend on what the use case is. What are you trying to do?
a

Ayfri

12/12/2021, 3:57 PM
I have 2 values, the first is a string and the second is a value from an Enum The second is changed through a DropDown menu, and I want the first to be equal to the name of the second But the first will later be used for multiple enums with other values like the second (I have a main DropDown menu which presents you other DropDowns that will all set my first value)
So I want to observe my second value to set the first value
a

Adam Powell

12/12/2021, 4:05 PM
how is the first value currently represented?
It sounds like the first value is always a function of the second, e.g.
val first: String get() = second.name
?
h

hfhbd

12/12/2021, 4:15 PM
Or use
derivedState
. But a regular extension method sounds simpler.
a

Adam Powell

12/12/2021, 4:24 PM
yeah
derivedStateOf
is a good choice if the calculation is expensive and the result should be cached; if not, just make it a function that calculates the result based on the input states
this is a kind of key element of declarative thinking with snapshots and compose; instead of thinking in terms of, "observe changes in value A and update value B accordingly," think in terms of, "B is defined as `f(A)`"
:thank-you: 1
by thinking this way you leave no room for error, no complexity of correct subscription management
everything is defined in terms of single sources of truth for each input instead of as data processing pipelines with discrete imperative stages and update events
a

Ayfri

12/12/2021, 4:33 PM
I can't use your solution Adam because I will maybe have other values that sets the first one My application is for creating JSON from templates, but there are types of JSONs and type of these types, like
Recipe
type and
Texture
type, and for recipes there is
CraftingShapedRecipeTemplate
and
CraftingShapelessRecipeTemplate()
and
SmeltingRecipeTemplate()
etc, same for
Texture
, there are multiple types But I have 1 box that contains the fields the user have to complete for the template, like
name
,
id
etc, there are a lot of different fields through the templates So to know what template I have, I have multiple Enums, like
RecipeType
and
TextureType
, and for each enum I have a function
toTemplate()
which transform itself into the template So for now when my second value changes, I set the first one to the Enum name and in the box I get back the template by searching through all the Enum if in any I can find a Enum value matching, using
MyEnum.values().find { it.name == firstValue } ?: MyOtherEnum.Values().find { it.name == firstValue } etc
and then I execute
.toTemplate()
or I return if null I don't know if it is a good architecture but I thought of this
a

Adam Powell

12/12/2021, 4:42 PM
yeah I would probably find another way to do that. 🙂 Even using an
Any
and a
when (value) { is EnumTypeOne -> ...
would be better than going through strings
1
but the general declarative principle will still guide you to a simpler design that will have fewer opportunities for bugs. "`first` is equal to..." and then whatever logic is involved in determining its value, absent any element of time or events.
a

Ayfri

12/12/2021, 4:49 PM
Okay I'm gonna use the
when (...) { is ...
so