Rofie Sagara
Rofie Sagara

Reputation: 333

Android dataStore with flow not get update after edit

I'm use DataStore with flow but I cant get any update on the flow when editing DataStore.

Store.kt

private class IStore(private val context: Context): Store {
    val eventIDKey = stringPreferencesKey("EventID")

    override suspend fun setEventID(eventID: String) {
        context.dataStoreSettings.edit { settings ->
            settings[eventIDKey] = eventID
        }
    }

    override fun getEventID(): Flow<String> {
        return context.dataStoreSettings.data.map { settings -> settings[eventIDKey].orEmpty() }
    }
}

and manipulate getEventID() with data from room database in event service

EventService.kt

fun getSelectedEventLive() = store.getEventID()
    .onEach { Log.d("EventService", "income new event id $it") }
    .flatMapConcat { if(it.isNotBlank()) eventDao.get(it) else flowOf(null) }

onEach called when I collect the data but when updated it's not called again and need to close and open the app to show the latest data

MainViewModel.kt

val selectedEvent = eventService.getSelectedEventLive()
    .stateIn(viewModelScope, SharingStarted.Lazily, null)

and use on Compose with this

val currentEvent by mainViewModel.selectedEvent.collectAsState()

Maybe I doing wrong or maybe there is something I miss?

Upvotes: 1

Views: 1596

Answers (2)

Rofie Sagara
Rofie Sagara

Reputation: 333

Yeah i found the solusion its works if i change the flatMapConcat with flatMapLatest in EventService.kt

fun getSelectedEventLive() = store.getEventID()
    .filterNot { it.isBlank() }
    .flatMapLatest { eventDao.get(it) }

Upvotes: 1

Steyrix
Steyrix

Reputation: 3226

Usually, you want to use flow.collect {...}, since Flow is cold and need to know that it is being collected to start producing new values.

// MainViewModel.kt
private val _selectedEvent = MutableStateFlow<TypeOfYourEvent>()
val selectedEvent: StateFlow<TypeOfYourEvent> = _selectedEvent

init {
    viewModelScope.launch {
        getSelectedEventLive().collect { it ->
            _selectedEvent.value = it    
        }
    }
}

This example should be fine with your composable's code, you still can collect selectedEvent as state.

Upvotes: 1

Related Questions