Cannot read and write in datastore preference manager

My app is to change the text when I choose a different language. I am not there yet. I am having difficulty reading the “language” and “position” from the datastore preference manager. The problem now is that I get null when I try to read “language” and “position”.

When I click one of the radio buttons in the bottom sheet and exit and then click the bottom sheet again to see if my favourite language remains checked. The bottom sheet remains clear and my favourite language didn’t remember the language I just click, the reason is that it cannot read the data from the preference and return “null”.

I am newbie to Android development. I have tried “Observe” but I cannot get the syntax right. Hopefully, anyone can help me to find the problem. Many thanks.

KC

Favourite Language Fragment

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val binding = FavouriteBottomSheetBinding.bind(view)


// Return null when trying to read data from PreferenceManager 
        val getFavouriteLanguage = viewModel.onFavouriteLanguage.value 

// Return null when trying to read data from PreferenceManager
        val getFavouritePosition = viewModel.onFavouritePosition.value 

        val favouriteAdapter = FavouriteAdapter(this, getFavouriteLanguage, getFavouritePosition)

        binding.apply {
            favouriteLanguageList.apply {
                adapter = favouriteAdapter
                layoutManager = LinearLayoutManager(requireContext())

            }
        }

        viewModel.favouriteLanguage.observe(viewLifecycleOwner) {
            favouriteAdapter.submitList(it)

        }

    }

    override fun onFavouriteLanguageClick(selectedFavouriteLanguage: String, position: Int) {
        viewModel.onSelectedFavouriteLanguage(selectedFavouriteLanguage)
        viewModel.onSelectedFavouritePosition(position)
        d("favouritebuttonclick", "$selectedFavouriteLanguage, $position")
    }


}

Favourite Langauge View Model

@HiltViewModel
class FavouriteViewModel @Inject constructor(
    languageDao: LanguageDao,
    private val preferencesManager: PreferencesManager
) : ViewModel() {

    val favouriteLanguage = languageDao.getFavouriteLanguageByName().asLiveData()

    //  Trying to read the data from preference manager for language and position
    val onFavouriteLanguage = preferencesManager.favouriteLanguageFlow.asLiveData()
    val onFavouritePosition = preferencesManager.favouritePositionFlow.asLiveData()

    fun onSelectedFavouriteLanguage(selectedFavouriteLanguage: String) =  viewModelScope.launch {
        d("viewmodelvariable", selectedFavouriteLanguage)
        preferencesManager.updateSelectedFavouriteLanguage(selectedFavouriteLanguage)
    }

    fun onSelectedFavouritePosition(selectedFavouritePosition: Int) =  viewModelScope.launch {
        d("viewmodelvariable", "$selectedFavouritePosition")
        preferencesManager.updateSelectedFavouritePosition(selectedFavouritePosition)
    }

}

Preferences Manager

@Singleton
class PreferencesManager @Inject constructor(@ApplicationContext context: Context) {

private val dataStore = context.dataStore
val preferencesFlow = dataStore.data
    .catch { exception ->
        if (exception is IOException) {
            Log.e(TAG, "Error reading preferences", exception)
            emit(emptyPreferences())
        } else {
            throw exception
        }
    }
    .map { preferences ->
        val sortOrder = SortOrder.valueOf(
            preferences[PreferencesKeys.SORT_ORDER] ?: SortOrder.BY_NAME.name
        )
        val hideSelectedLanguage = preferences[PreferencesKeys.HIDE_SELECTED_LANGUAGE] ?: false
        FilterPreferences(sortOrder, hideSelectedLanguage)

    }


suspend fun updateSortOrder(sortOrder: SortOrder) {
    dataStore.edit { preferences ->
        preferences[PreferencesKeys.SORT_ORDER] = sortOrder.name
    }
}

suspend fun updateHideSelectedLanguage(hideSelectedLanguage: Boolean) {
    dataStore.edit { preferences ->
        preferences[PreferencesKeys.HIDE_SELECTED_LANGUAGE] = hideSelectedLanguage
    }
}

suspend fun updateSelectedFavouriteLanguage(selectedFavouriteLanguage: String) {
    Log.d("preferencevariable", selectedFavouriteLanguage)
    dataStore.edit { preferences ->
        preferences[PreferencesKeys.SELECTED_FAVOURITE_LANGUAGE] = selectedFavouriteLanguage
    }
}

suspend fun updateSelectedFavouritePosition(selectedFavouritePosition: Int) {
    Log.d("preferencevariable", selectedFavouritePosition.toString())
    dataStore.edit { preferences ->
        preferences[PreferencesKeys.SELECTED_FAVOURITE_POSITION] =
            selectedFavouritePosition
    }
}

 // Try to read language from datastore 
val favouriteLanguageFlow: Flow<String?> = dataStore.data
    .catch { exception ->
        if (exception is IOException) {
            Log.e(TAG, "Error while trying to read user preferences", exception)
            emit(emptyPreferences())
        } else {
            throw exception
        }
    }
    .map { preferences ->
        preferences[PreferencesKeys.SELECTED_FAVOURITE_LANGUAGE]

    }

// Try to read language position from datastore
val favouritePositionFlow: Flow<Int?> = dataStore.data
    .catch { exception ->
        if (exception is IOException) {
            Log.e(TAG, "Error while trying to read user preferences", exception)
            emit(emptyPreferences())
        } else {
            throw exception
        }
    }
    .map { preferences ->
        preferences[PreferencesKeys.SELECTED_FAVOURITE_POSITION]

    }


private object PreferencesKeys {
    val SORT_ORDER = stringPreferencesKey("sort_order")
    val HIDE_SELECTED_LANGUAGE = booleanPreferencesKey("hide_selected_language")
    val SELECTED_FAVOURITE_LANGUAGE = stringPreferencesKey("selected_favourite_language")
    val SELECTED_FAVOURITE_POSITION = intPreferencesKey("selected_favourite_position")
}

}

Favourite Language Adapter

class FavouriteAdapter(
    private val listener: OnFavouriteLanguageClickListener,
    favouriteLanguage: String?,
    favouritePosition: Int?
) :
    ListAdapter<Language, FavouriteAdapter.FavouriteViewAHolder>(DiffCallback()) {

    private var selectFavouritePosition = favouritePosition
    private var selectLanguage = favouriteLanguage

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FavouriteViewAHolder {
        val binding =
            ItemFavouriteBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return FavouriteViewAHolder(binding)
    }

    override fun onBindViewHolder(holder: FavouriteViewAHolder, position: Int) {

        val currentItem = getItem(position)
        holder.bind(currentItem, position, selectFavouritePosition, selectLanguage)

        holder.favouriteLanguageRadioButton.setOnClickListener {
            d("testbutton", "show test")
            selectFavouritePosition = holder.adapterPosition
            selectLanguage = currentItem.language
            d("holderlistener", "$selectLanguage, $selectFavouritePosition")
            listener.onFavouriteLanguageClick(selectLanguage!!, selectFavouritePosition!!)
            notifyDataSetChanged()

        }


    }

    inner class FavouriteViewAHolder(private val binding: ItemFavouriteBinding) :
        RecyclerView.ViewHolder(binding.root) {

        val favouriteLanguageRadioButton = binding.rbIsClicked

        fun bind(
            language: Language,
            position: Int,
            selectFavouritePosition: Int?,
            selectLanguage: String?
        ) {
            binding.apply {

                tvFavouriteLanguage.text = language.language
                d("selectFavourite", "$selectFavouritePosition")
                d("selectFavourite", "$selectLanguage")

                if (selectFavouritePosition == -1 && position == 0) {
                    favouriteLanguageRadioButton.isChecked = false
                } else if (selectFavouritePosition != position && selectLanguage != language.language) {
                    favouriteLanguageRadioButton.isChecked = false
                } else if (selectFavouritePosition == position && selectLanguage == language.language) {
                    favouriteLanguageRadioButton.isChecked = true
                }
            }
        }

    }

    interface OnFavouriteLanguageClickListener {
        fun onFavouriteLanguageClick(selectedFavouriteLanguage: String, position: Int)
    }


    class DiffCallback : DiffUtil.ItemCallback<Language>() {

        override fun areItemsTheSame(oldItem: Language, newItem: Language) =
            oldItem.id == newItem.id

        override fun areContentsTheSame(oldItem: Language, newItem: Language) = oldItem == newItem

    }

}