Coroutines Flow with Dao and generic Result class

Akshay Taru :

I have a Dao class which returns List of Car objects as flow.

@Query("SELECT * FROM Car")
fun getAllCars(): Flow<List<Car>>

In my repository, I can use this Dao as follows

fun getAllCars(): Flow<List<Car>>
//Implementation
override fun getAllCars() = carDao.getAllCars()

I can observe this flow in view model and everything works and life was fine.

Now, after reading the post on Developer Android site about

A generic class that contains data and status about loading this data.

I got inspired, so I read one more post here which discuss about having Result class.

So, I have done some changes to repository and I am not able to solve them.

Error:


suspend fun getSomeData(): Flow<Result<List<Car>>> {
        carDao.getAllCars().collect {
            if (it.isNotEmpty()) {
                return flowOf(Result.Success(it))  //<-- Here I am getting error from IDE
            }
            else {
                val throwable = Throwable()
                return flowOf(Result.Failure<List<Car>>(throwable)) //<-- Here I am getting error from IDE
            }
        }
    }

The error is Return is not allowed here and Change to 'return@Collect'

What I want to achieve is:

// At view model side
viewmodelScope.launch {

    repo.getSomeData().collect {
      if (it == Result.Success) {
        //Show data
      }
      else {
        //Show empty screen
      }

    }
}

Is my approach of implementation of Result is wrong? I am not able to figure out what is wrong. Why I can't just return Flow from a flow

Marko Topolnik :

This is what your function should look like. Note there's no need for it to be a suspend fun.

fun getSomeData(): Flow<Result<List<Car>>> = flow {
    carDao.getAllCars().collect {
        if (it.isNotEmpty()) {
            emit(Result.Success(it))
        }
        else {
            emit(Result.Failure<List<Car>>(Throwable()))
        }
    }
}

But what it does is nothing more than adding a mapping step, which you can generalize.

fun <T> Flow<List<T>>.toResultFlow(): Flow<Result<List<T>>> = this.map {
    if (it.isNotEmpty()) Result.Success(it)
    else Result.Failure(Throwable())
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=174978&siteId=1