'how to return an object in a suspended function after receiving the object from a Flow?

I'm wondering if there's a way to wait for a flow to be complete and return the result inside a suspend function. transactionRepository.getAll(accountId) returns a flow of transactions

override suspend fun getAccount(accountId: Int): Account {
    val account = Account(accountRepository.get(accountId))
    transactionRepository.getAll(accountId).mapIterable {
        val transaction = Transaction(it)
        val category = Category(categoryRepository.get(it.categoryId))
        transaction.category = category
        transaction.account = account
        return@mapIterable transaction
    }.collect {
        account.transactions = it
     }

    //TODO: How can i return an account after the flow has been executed?
}

getAll function defined in my repository:

fun getAll(accountId: Int): Flow<List<DatabaseTransaction>>


Solution 1:[1]

Assuming you want just the first value returned by the flow, and it's a List<Transaction>, you can use first(). But I'm only guessing because I don't know what getAll() returns and I'm not familiar with mapIterable.

override suspend fun getAccount(accountId: Int): Account {
    val account = Account(accountRepository.get(accountId))
    val transactionsFlow: Flow<List<Transaction>> = transactionRepository.getAll(accountId).mapIterable {
        val transaction = Transaction(it)
        val category = Category(categoryRepository.get(it.categoryId))
        transaction.category = category
        transaction.account = account
        return@mapIterable transaction
    }
    account.transactions = transactionsFlow.first()
    return account
}

Solution 2:[2]

You could do two things

First one would be to use the .toList() on the flow which I think gives you the list you want then you can just do a normal for loop on that list to set the data

val transactions = transactionRepository.getAll(accountId).toList()

transactions.forEach{
    val transaction = Transaction(it)
    val category = Category(categoryRepository.get(it.categoryId))
    transaction.category = category
    transaction.account = account
}

account.transactions = transactions 

Second would be to just return the account after the collect like you normally would.

val account = Account(accountRepository.get(accountId))
transactionRepository.getAll(accountId).mapIterable {
    val transaction = Transaction(it)
    val category = Category(categoryRepository.get(it.categoryId))
    transaction.category = category
    transaction.account = account
    return@mapIterable transaction
}.collect {
    account.transactions = it
 }

return account

See this example I made

https://pl.kotl.in/wWmLiqBtz

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 tyczj