Home > Software engineering >  How to initialize a flow in viewmodel with a suspend function as parameter
How to initialize a flow in viewmodel with a suspend function as parameter

Time:01-26

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.

CodePudding user response:

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)

CodePudding user response:

as I know you can call suspend fun in variable it must in init or in function There is another solution

       @HiltViewModel
    class SubscriptionViewModel @Inject constructor(
        private val userDataStore: UserDataStore,
        private val walletDao: WalletDao
    ) : ViewModel() {
    
    val flow= MutableStateFlow<List<Transcation>>(listOf())
   
   // then add value in init or anywhere 
     init {
            viewModelScope.launch(IO) {
                flow.emit() // add value here
            }
        }
    }
  •  Tags:  
  • Related