How would you people improve this code? ```suspend...
# arrow
j
How would you people improve this code?
Copy code
suspend fun <T> getListWrapperFromDbAnApi(
    getFromDb: suspend () -> Either<InOrderError, ListWrapper<T>>,
    shouldUpdate: (List<T>) -> Boolean,
    getFromApi: suspend () -> Either<InOrderError, ListWrapper<T>>,
    saveDataFromApi: suspend (List<T>) -> Either<InOrderError, Unit>
) = flow {
        getFromDb().fold(
            { emit(Either.Left(it)) },
            { dbData ->
                emit(Either.Right(dbData))
                if (shouldUpdate(dbData.items)) {
                    getFromApi().fold(
                        { emit(Either.Left(it)) },
                        { apiData ->
                            if (dbData != apiData) {
                                emit(Either.Right(apiData))
                                saveDataFromApi(apiData.items)
                            }
                        }
                    )
                }
            }
        )
    }
I don’t think I can use
either.eager
due to the nested suspend function error
Restricted suspending functions can only invoke member or extension suspending functions on their restricted coroutine scope
s
But you can use
either { }
inside
flow { }
since it’s
suspend
, right? So something like this.
Copy code
flow {
  either<InOrderError, Unit> {
    val dbData = getFromDb().bind()
    emit(dbData)
    if(shouldUpdate(db.item)) {
      val apiData = getFromApi().bind()
      if(dbData != apiData ) {
        emit(apiData.right())
        saveDataFromApi(apiData.items)
      }
    }
  }.fold({ emit(it.left()) }, ::identity)
}
💯 2
j
TIL about
either
, thanks @simon.vergauwen!
.fold({ emit(it.left()) }, ::identity)
is also pretty neat
not so nice after all, I had to do this in order to make it work properly
Copy code
flow {
    val collector = this
    either<InOrderError, Unit> {
        val dbData = getFromDb().bind()
        collector.emit(Either.Right(dbData))
        if (shouldUpdate(dbData.items)) {
            val apiData = getFromApi().bind()
            if (dbData != apiData) {
                collector.emit(Either.Right(apiData))
                saveDataFromApi(apiData.items)
            }
        }
    }.fold({ emit(it.left()) }, ::identity)
}
emit
isn’t directly accessible inside
either
since lambdas have different scope
s
That is very strange… I’ll try this example
either
is even
inline
Works fine for me
p
Copy code
.fold({ emit(it.left()) }, ::identity)
mapLeft
here
j
This little guy break the whole thing
emit(dbData)
, using
emit(dbData.right())
instead fixed the issue