0

I'm working on an application that uses WorkerManager for background tasks, most of the time it's used to send requests to the backend and process the received data, I thought it would be a great idea to use LiveData (or Flow) to automatically update UI after new data is saved to the database, but it doesn't work as i expected, the flow does not emit data after it saved to the db

In my background worker, I have an async method that loads the data to backend after the user clicks the "save" button.

override suspend fun doWorkWithRetry(): Result = coroutineScope {
    val one = processCreatedReceipts()
    if (one.await() * other async methods *) {
        Result.success()
    } else {
        throw RuntimeException("Failed to upload data")
    }
}
@OptIn(DelicateCoroutinesApi::class)
private fun processCreatedReceipts() = GlobalScope.async {
    val data: List<Expenses> = expensesRepo.findAllBySyncState(SyncState.UNSYNCED)
    data.parallelStream().forEach { expense ->
        val dto = expense.asCreateDto()
        expensesService.createReceipt(dto).run { r, t ->
            t?.let {
                expensesRepo.updateSyncStateById(expense.id, SyncState.SYNC_FAILED)
                throw RuntimeException("Data sync failed with error: ${t.message}")
            }
            r?.data?.result?.let { result ->
                 * save to received data to db *
            }
        }
    }
}

From the UI I get the list of data as a flow using this method in the DAO object

@Query(
        """
        SELECT *
        FROM files
        WHERE resourceId == :id and sync_state is not 'PENDING_DELETE'
        """
    )
    abstract fun findByIdFlow(id: String?): Flow<List<FileData>>

I create a Flow inside a Fragments viewModel using

val list: Flow<List<FileData>> = repo.findByIdFlow(userId)

And I collect data in a fragment using

lifecycleScope.launch(Dispatchers.IO) {
    viewModel.list.collect {         
        lifecycleScope.launch(Dispatchers.Main) {             
            * update UI *         
        }     
    }
}

Could this be a problem with the async methods what saved data to db or am I getting the data from db in wrong way?

3
  • how/where are you observing/collecting the flow? Commented Oct 2, 2024 at 12:51
  • @tyczj I create flow in viewModel fragments val list: Flow<List<ExpensesWithFile>> = repo.findWithFile(userId) I collect data inside fragment in that way lifecycleScope.launch(Dispatchers.IO) { viewModel.list.collect { lifecycleScope.launch(Dispatchers.Main) { * update UI method * } } } Commented Oct 2, 2024 at 13:13
  • please edit the question, do not put the code in your comment Commented Oct 2, 2024 at 13:33

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.