Search code examples
androidandroid-roomkotlin-coroutinesandroid-mvvm

value returned from SQLite using Room Persistence is not being assigned to MutableLiveData


I want to calculate sum of weight field of all records in table myTable, I tried:

@Entity(tableName = "myTable")
data class Foo(
    @ColumnInfo(name = "purchaseWeight")
    val weight: Int,
    @ColumnInfo(name = "purchaseDate")
    val date: Long,
    val description: String?

) {

    @PrimaryKey(autoGenerate = true)
    var id: Int = 0

}

and other class

data class Sum(val sum: Int)

In Dao class

@Dao
interface FooDAO {
    @Query("SELECT SUM(purchaseWeight) AS sum FROM myTable")
    suspend fun calculateSumOfAllWeight(): Sum  
}

In repository class

class FooRepository(application: Application) {

    private var fooDAO: FooDAO

    private var sumOfAllWeight = MutableLiveData<Int>()

    init {
        // skipping other code
        CoroutineScope(Dispatchers.IO).launch {
             Log.e(TAG, "Got sum "+ fooDAO.calculateSumOfAllWeight().sum) // Here it prints actual sum of all records
             sumOfAllWeight.postValue(fooDAO.calculateSumOfAllWeight().sum) // but here value is never assigned to MutableLiveData<Int> which is sumOfAllWeight variable
        }
    }

    fun getSumOfAllWeight(): MutableLiveData<Int> {    
        Log.e(TAG, " sumOfAllWeight "+ sumOfAllWeight.value) // it prints null
        return sumOfAllWeight    
    }    
}

ViewModel class is:

class FooViewModel(
    application: Application
): AndroidViewModel(application) {

    private var repository = FooRepository(application) 

    fun getSumOfAllWeight():MutableLiveData<Int> {
        return repository.getSumOfAllWeight()
    }
}

and MainActivity.kt is:

class MainActivity : AppCompatActivity(){

    private lateinit var mFooViewModel: FooViewModel

    private var sumOfAllWeight = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        mFooViewModel = ViewModelProviders.of(this).get(FooViewModel::class.java)

        mFooViewModel.getSumOfAllWeight().observe(
            this,
            Observer {
                sumOfAllWeight = it
            }
        )

        // Set Values to top TextViews
        tv_sum_lbl.text =   "$sumOfAllWeight - KG(s)"  // Here  is set to this view          
    }
}

but It prints

E/SUM_OF_WEIGHT: sumOfAllWeight null
E/SUM_OF_WEIGHT: Got sum 324

could not figure out why value is not being assigned at sumOfAllWeight.postValue(fooDAO.calculateSumOfAllWeight().sum) to MutableLiveData<Int>.


Solution

  • Inside your activity sumOfAllWeight is not observable. So it's not reflect when changes outside observer. Check with below code:

    mFooViewModel.getSumOfAllWeight().observe(
        this,
        Observer {
            tv_sum_lbl.text =   "$it - KG(s)" // Now check value here
        }
    )