Pablo
06/12/2024, 11:20 AMPablo
06/12/2024, 11:21 AMuserPreferencesRepository.searchText
This is the datastore value code, in my datastore repo class:
val searchText: Flow<String> = dataStore.data
.catch {
if (it is IOException) {
Log.e(TAG, "Error reading preferences.", it)
emit(emptyPreferences())
} else {
throw it
}
}
.map { preferences ->
preferences[SEARCH_TEXT] ?: ""
}
Khubaib Khan
06/12/2024, 11:25 AMclass MyViewModel(private val userPreferencesRepository: UserPreferencesRepository) : ViewModel() {
val searchTextFlow: Flow<String> = userPreferencesRepository.searchText
}
Now Collect the Flow
inside your Composable using collectAsStateWithLifecycle
@Composable
fun MyTextField(viewModel: MyViewModel) {
// Collect the searchText Flow as a state
val searchText by viewModel.searchTextFlow.collectAsStateWithLifecycle(initialValue = "")
var text by remember { mutableStateOf(searchText) }
TextField(
value = text,
onValueChange = { newText ->
text = newText
// You can add code here to save the newText to DataStore if needed
},
label = { Text("Search") }
)
}
Pablo
06/12/2024, 11:35 AMfun updateSearchText(searchText: String) {
viewModelScope.launch {
userPreferencesRepository.saveSearchTextPreference(searchText)
}
}
which calls to this in the datapreferences repo:
suspend fun saveSearchTextPreference(searchText: String) {
dataStore.edit { preferences ->
preferences[SEARCH_TEXT] = searchText
}
}
Pablo
06/12/2024, 11:39 AM.map { preferences ->
preferences[SEARCH_TEXT] ?: ""
}
And it is recovering the stored value, but it's too late, because the composable has been already presented with empty text. Why?Khubaib Khan
06/12/2024, 11:40 AMclass UserPreferencesRepository(context: Context) {
private val dataStore: DataStore<Preferences> = context.createDataStore(name = "user_preferences")
val searchText: Flow<String> = dataStore.data
.catch {
if (it is IOException) {
Log.e(TAG, "Error reading preferences.", it)
emit(emptyPreferences())
} else {
throw it
}
}
.map { preferences ->
preferences[SEARCH_TEXT] ?: ""
}
suspend fun saveSearchTextPreference(searchText: String) {
dataStore.edit { preferences ->
preferences[SEARCH_TEXT] = searchText
}
}
}
// MainViewModel:
class MyViewModel(private val userPreferencesRepository: UserPreferencesRepository) : ViewModel() {
val searchTextFlow: Flow<String> = userPreferencesRepository.searchText
fun updateSearchText(searchText: String) {
viewModelScope.launch {
userPreferencesRepository.saveSearchTextPreference(searchText)
}
}
}
// COmposabe
@Composable
fun MyTextField(viewModel: MyViewModel) {
// Collect the searchText Flow as a state
val searchText by viewModel.searchTextFlow.collectAsStateWithLifecycle(initialValue = "")
var text by remember { mutableStateOf(searchText) }
// TextField to display and edit the text
TextField(
value = text,
onValueChange = { newText ->
text = newText
viewModel.updateSearchText(newText) // Save the new text to DataStore
},
label = { Text("Search") }
)
}
Pablo
06/12/2024, 11:41 AMPablo
06/12/2024, 11:42 AMKhubaib Khan
06/12/2024, 11:43 AMKhubaib Khan
06/12/2024, 11:45 AM@Composable
fun MyTextField(viewModel: MyViewModel) {
val searchText by viewModel.searchTextFlow.collectAsState(initial = "")
var text by rememberUpdatedState(searchText)
LaunchedEffect(Unit) {
viewModel.searchTextFlow.collect { newText ->
text = newText
Log.d("Composable", "Text state updated to: $newText")
}
}
TextField(
value = text,
onValueChange = { newText ->
text = newText
viewModel.updateSearchText(newText)
},
label = { Text("Search") }
)
}
Khubaib Khan
06/12/2024, 11:45 AMPablo
06/12/2024, 11:49 AMPablo
06/12/2024, 11:49 AMType 'State<String>' has no method 'setValue(Nothing?, KProperty<*>, String)' and thus it cannot serve as a delegate for var (read-write property)
Pablo
06/12/2024, 11:50 AMPablo
06/12/2024, 11:50 AMPablo
06/12/2024, 11:50 AMKhubaib Khan
06/12/2024, 11:50 AMKhubaib Khan
06/12/2024, 11:52 AMKhubaib Khan
06/12/2024, 11:55 AM.map { preferences ->
preferences[SEARCH_TEXT] ?: ""
}
Pablo
06/12/2024, 11:57 AMKhubaib Khan
06/12/2024, 11:58 AMPablo
06/12/2024, 4:42 PMPablo
06/12/2024, 4:42 PM