Hi <@UHAJKUSTU>, all good things are three so here...
# decompose
j
Hi @Arkadii Ivanov, all good things are three so here is another question. More in thread:
I have a RootComponent with a SlotNavigation
Within that RootComponent I have a flow to determine the state of the app and I start listining to it within the init of RootComponent
An initial slot is activated und slotNavigation persistent is set to true
After orientation change occured the flow is somehow broken due I do not get events anymore
Its working again if I explicit dismiss the last active config in my slot navigation on destroy
I have the feeling that the slotChild does somehow not recognize that a new component was created due orientation change and probably leaks
My RootComponent looks something like this:
Copy code
class RootComponent(
    private val componentContext: ComponentContext,
    private val getRootState: GetRootStateUsecase
) : ComponentContext by componentContext, KoinComponent {
private val slotNavigation = SlotNavigation<SlotConfig>()

    private val _slot = childSlot(
        source = slotNavigation,
        initialConfiguration = { SlotConfig.Home }
    ) { config, childComponentContext ->
        when (config) {
            else ->
                HomeComponent(
                    componentContext = childComponentContext,
                    componentViewModel = childComponentContext.instanceKeeper.getOrCreate {
                        getKoin().get()
                    },
                    headerViewModel = childComponentContext.instanceKeeper.getOrCreate {
                        getKoin().get()
                    }
                )
        }
    }

    val slot: Value<ChildSlot<*, *>> = _slot

    private val componentScope = coroutineScope(Dispatchers.Main + SupervisorJob())

    init {
        lifecycle.doOnDestroy {
            //slotNavigation.dismiss()
        }

        componentScope.launch {
            getRootState().collect { config ->
                println("RootComponent received new state config: $config")

            }
        }
    }
}
is that correct that I have to dismiss it manually even though I set persitent = true on my slotNavigation?
a
The "persistent" flag means that the slot will stay active on configuration change. So you usually don't need to manually close the slot on destroy.
j
Yes, but unfortunately if I don't do so my flow breaks
a
Can you show more code? What is getRootState?
j
Its just a UseCase wich links to a repository and returns a flow:
Copy code
class GetRootStateUsecase(
    private val rootStateRepository: RootStateRepository
) {
    suspend operator fun invoke(): Flow<RootComponent.SlotConfig> = rootStateRepository.getState()
}
Copy code
interface RootStateRepository {
    suspend fun getState(): Flow<RootComponent.SlotConfig>
}

class RootStateRepositoryImpl(
    private val ioDispatcher: CoroutineDispatcher,
    private val venueRepository: VenueRepository,
    private val userRepository: UserRepository
) : RootStateRepository {

    override suspend fun getState(): Flow<RootComponent.SlotConfig> = flow {
        val selectedVenueFlow = venueRepository.getSelectedVenue()
        val selectedUserFlow = userRepository.getSelectedUser()
        selectedVenueFlow.combine(selectedUserFlow) { selectedVenue, selectedUser ->
            State(
                venue = selectedVenue,
                user = selectedUser
            )
        }.distinctUntilChanged().collect {
            if (it.venue == null) {
                emit(RootComponent.SlotConfig.Inventory)
            } else if (it.user == null) {
                emit(RootComponent.SlotConfig.Login)
            } else {
                emit(RootComponent.SlotConfig.Dashboard)
            }
        }
    }.flowOn(ioDispatcher)
}

private data class State(
    val venue: Venue?,
    val user: User?
)
If I use a stack-navigation instead of slot-navigation it seems to work correctly
a
Thanks. Based on the code I can't say what's wrong. I recommend to create a minimal reproducer so I could check.
j
ok, I will. It feels like that slot within the composable is somehow not in sync anymore
a
I suspect you have a leak in either componentViewModel or headerViewModel
j
probably but I thing I checked that
a
But I would rather find the leak
j
hehe
me too 😉
ok, I think I found my leak
🎉 1
sorry for bothering you
a
Yay!
j
ok, it was not even a leak!
I stopped started/stopped koin during orientation change (oncreate/ondestroy in activity) and therefore my viewmodels broke
a
Thanks for sharing! Koin was my second suspect. 😀