Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize a flow in viewmodel with a suspend function as parameter

I am working with room database and datastore . Here is my code

ViewModel

@HiltViewModel
class SubscriptionViewModel @Inject constructor(
    private val userDataStore: UserDataStore,
    private val walletDao: WalletDao
) : ViewModel() {

val flow: Flow<List<Transaction>> = walletDao.getAllTransactions(userDataStore.getId()) 
 // This shows an error as userDataStore.getId() is a suspend function in DataStore


 init {
        viewModelScope.launch(IO) {
            getWalletAmount()
        }
    }
}

DataStore

 suspend fun getId(): String {
        val preferences = dataStore.data.first()
        return preferences[USER_ID] ?: ""
    }

WalletDao

 @Query("SELECT * FROM recent_transactions where user_id=:user_id")
    fun getAllTransactions(user_id: String): Flow<List<Transaction>>

The problem is I am unable to initialise the flow. I tried initialising it in the init{ } block using lateinit , but while accessing in the fragment it crashes saying flow has not been initialised.

Any solution would help.

like image 760
Ankit Verma Avatar asked Oct 22 '25 00:10

Ankit Verma


1 Answers

You can wrap it in a flow builder.

val flow: Flow<List<Transaction>> = flow {
    val source = walletDao.getAllTransactions(userDataStore.getId())
    emitAll(source)
}

If you want it to pre-load (start getting the first value even before anything collects the flow), then you should turn it into a SharedFlow by tacking this on:

.shareIn(viewModelScope, SharingStarted.Eagerly, replay = 1)
like image 133
Tenfour04 Avatar answered Oct 24 '25 14:10

Tenfour04