Home > Blockchain >  Observing database using flow
Observing database using flow

Time:05-10

I am having trouble to implement this feature below.

Let's say I hava a Content class.

interface ContentDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertContent(content: Content)

    @Query("query to get content with id")
    fun getContent(contentId: Long): Flow<Content>
}

I should not directly observe this in ui layer. Instead i need something like this

fun getContent(contentId: Long) : Flow<State> = flow {
    emit(State.Loading)
    val response = handle {api.getContent(contentId)}
    if (response !is Success) {
        emit(State.Error)
        return@flow
    } else {
        appDatabase.contentDao.insertContent(response.getContent())

        appDatabase.contentDao.getContent(contentId).collect {
            emit(State.Content(it))
        }
    }
}

How can I implement this behaviour. Collector should not directly observe appdatabase. First it should update content. Then listen to database.

If something went wrong while updating content. It should emit Error state.

Thanks in advance!

CodePudding user response:

you can handle the insert function by throwing Exception if something went wrong:

@Insert(onConflict = OnConflictStrategy.REPLACE)
@Throws(SQLiteException::class)
suspend fun insertContent(content: Content)

and also in your case, I think you don't need to return flow in your content:

@Query("query to get content with id")
@Throws(SQLiteException::class)
suspend fun getContent(contentId: Long): Content

and in your function do this:

fun getContent(contentId: Long) : Flow<State> = flow {
    emit(State.Loading)
    val response = handle {api.getContent(contentId)}
    if (response !is Success) {
        emit(State.Error)
        return@flow
    } else {
        try {
            appDatabase.contentDao.insertContent(response.getContent())
            emit(appDatabase.contentDao.getContent(contentId))
        } catch (e: SQLiteException) {
            emit(State.Error)
        }
    }
}

CodePudding user response:

Thanks for all. From the code that I posted in my question, I was getting an exception. Because i was emitting value to a flow from different coroutine. I used channelFlow builder function (which hanldles communication between coruotines) instead of flow builder. Now everything is working fine.

  • Related