Search code examples
androidandroid-room

How can i get one item from Room database?


So, I have two ViewModels and two screens in my app. The first screen is for the presentation of a list of diary item elements, second is for detailed information on diary items. In a second ViewModel, I have an id to get a record from DB but can find it. What can I do to get it?

DAO:

interface DiaryDao {

    @Query("SELECT * FROM diaryItems")
    fun getAllDiaryPosts(): LiveData<List<DiaryItem>>

    @Query("Select * from diaryItems where id = :id")
    fun getDiaryPostById(id: Int) : DiaryItem

    @Query("Delete from diaryItems where id = :index")
    fun deleteDiaryPostByIndex(index : Int)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertDiaryPost(diaryItem: DiaryItem)

    @Update
    suspend fun updateDiaryPost(diaryItem: DiaryItem)

    @Delete
    suspend fun deleteDiaryPost(diaryItem: DiaryItem)

    @Query("Delete from diaryItems")
    suspend fun deleteAllDiaryItems()
    
}

Repository

class DiaryRepository @Inject constructor(private val diaryDao: DiaryDao) {

    val readAllData: LiveData<List<DiaryItem>> = diaryDao.getAllDiaryPosts()
   
    suspend fun getDiaryPostDyIndex(index: Int): DiaryItem {
        return diaryDao.getDiaryPostById(index)
    }
}

First viewmodel

@HiltViewModel
class PostListViewModel
@Inject
constructor(
    private val diaryRepository: DiaryRepository,
) : ViewModel() {
    private var allDiaryItems: LiveData<List<DiaryItem>> = diaryRepository.readAllData
}

Second viewmodel

@HiltViewModel
class PostDetailViewModel
@Inject
constructor(
    private val savedStateHandle: SavedStateHandle,
    private val diaryRepository: DiaryRepository
) : ViewModel() {


    sealed class UIState {
        object Loading: UIState()
        data class Success(val currentPosts: DiaryItem) : UIState()
        object Error : UIState()
    }

    val postDetailState: State<UIState>
        get() = _postDetailState
    private val _postDetailState = mutableStateOf<UIState>(UIState.Loading)


    init {
        viewModelScope.launch (Dispatchers.IO) {
           try {

                   val diaryList: DiaryItem = diaryRepository.getDiaryPostDyIndex(2) //it is for test
                   _postDetailState.value = UIState.Success(diaryList)

           } catch (e: Exception) {
               withContext(Dispatchers.Main) {
                   _postDetailState.value = UIState.Error
               }
           }
        }

    }

}

Solution

  • I am sure you are getting errors. because you updating UI State in IO Thread

    fun getDairyItem(itemId: Int){
    viewModelScope.launch (Dispatchers.IO) {
         try {
               val diaryList: DiaryItem = diaryRepository.getDiaryPostDyIndex(itemId)
               withContext(Dispatchers.Main) {
                  _postDetailState.value = UIState.Success(diaryList)
               } 
               } catch (e: Exception) {
                   withContext(Dispatchers.Main) {
                       _postDetailState.value = UIState.Error
                   }
               }
            }
    }