title: Unable to get the ViewModel to show data after querying the ROOM database with parameters (Kotlin)
body: <p>First of all I have to say that I am rather new to Kotlin, and after spending 5 days (35+ hours) trying to google this issue and trying countless different options (similar questions on stack overflow, documentation and tutorials found on Google, other Kotlin projects on GitHub, even using my own server and database wondering if the issue has something to do with ROOM) I have to give up and ask for help, as this app is for an assignment I am supposed to finish in a couple of weeks.</p>
  
  <p>Description of the app (Expense tracker):</p>
  
  <ul>
  <li>When you open the app, you see the the HomeFragment, which shows recently added expenses. </li>
  <li>There is a Add Expense fragment/tab where you can add expenses: Write down the expense name and amount, choose category from the spinner and the date from the date picker (default: today).</li>
  <li>There is a Totals fragment/tab where you can see statistics/data of your expenses. I have a Category spinner and Time options spinner (Today, This month, This year, All time), and when the user clicks the button, I am building a query from the selected options and want to display data according to the user's preferences on my RecyclerView below.</li>
  <li>Above the RecyclerView you can see your expenses, income and total (total = income - expenses, using SELECT SUM query to get income and expenses once I have figured this part out), and the RV should just be a list of the result of the query, and the user could delete single expenses by swiping to the left (very basic stuff, already works on the HomeFragment where the RV shows just fine with the static query).</li>
  </ul>
  
  <p>I feel like I have tried literally everything - Especially Transformations.switchMap as many results seem to point that way, but I haven't made any progress whatsoever. I have browsed through dozens of apps on GitHub to see how theirs work, trying to implement the logic in mine, but even if after all the time I manage to adjust the code so that I get no errors, nothing is still shown on my RecyclerView.</p>
  
  <p>Here are the snippets from the classes that I believe are relevant to this issue (in the order from most relevant to somewhat relevant, some parts of the code omitted to not flood this post completely):</p>
  
  <p><strong>TotalsFragment:</strong></p>
  
  <pre><code>import android.os.Bundle
  import androidx.fragment.app.Fragment
  import android.view.LayoutInflater
  import android.view.View
  import android.view.ViewGroup
  import android.widget.AdapterView
  import android.widget.ArrayAdapter
  import androidx.appcompat.app.AppCompatActivity
  import androidx.lifecycle.Observer
  import androidx.lifecycle.ViewModelProviders
  import androidx.recyclerview.widget.DividerItemDecoration
  import androidx.recyclerview.widget.ItemTouchHelper
  import androidx.recyclerview.widget.LinearLayoutManager
  import androidx.recyclerview.widget.RecyclerView
  import com.example.expensetracker.R
  import com.example.expensetracker.model.Category
  import com.example.expensetracker.model.Expense
  import com.google.android.material.snackbar.Snackbar
  import kotlinx.android.synthetic.main.fragment_totals.*
  import java.util.*
  import kotlin.collections.ArrayList
  
  class TotalsFragment : Fragment() {
  
      private val totals: MutableList&lt;Expense&gt; = ArrayList()
      private val totalAdapter = ExpenseAdapterTotals(totals)
      private lateinit var viewModel: TotalsViewModel
  
      // 
      // Bunch of variables omitted 
      //  
  
  
      override fun onCreateView(
          inflater: LayoutInflater, container: ViewGroup?,
          savedInstanceState: Bundle?
      ): View? {
  
          // Initialize the ViewModel
          viewModel = ViewModelProviders.of(activity as AppCompatActivity).get(TotalsViewModel::class.java)
  
          // Inflate the layout for this fragment
          return inflater.inflate(R.layout.fragment_totals, container, false)
      }
  
      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
          super.onViewCreated(view, savedInstanceState)
  
          updateUI()
          initViewModel()
          initViews()
          initCategorySpinner()
          initTimeSpinner()
  
          // For getting data and updating the UI after the button is clicked
          btn_show.setOnClickListener {
              updateRvData()
              updateTotals()
              updateUI()
          }
  
      }
  
      private fun initViewModel(){
          viewModel = ViewModelProviders.of(this).get(TotalsViewModel::class.java)
  
          viewModel.totals.observe(this, Observer {
              if (totals.isNotEmpty()) {
                  totals.clear()
              }
              totals.addAll(it!!)
  
              totalAdapter.notifyDataSetChanged()
          })
  
      }
  
      private fun initViews(){
          createItemTouchHelper().attachToRecyclerView(rv_expenses_totals)
          rv_expenses_totals.apply {
              layoutManager = LinearLayoutManager(activity)
              rv_expenses_totals.adapter = totalAdapter
              rv_expenses_totals.addItemDecoration(DividerItemDecoration(this.context, DividerItemDecoration.VERTICAL))
          }
      }
  // Code omitted
  </code></pre>
  
  <p>The part sending the query forward:
  <code>viewModel.getTotals(queryString)</code></p>
  
  <p><strong>TotalsViewModel:</strong></p>
  
  <pre><code>import android.app.Application
  import androidx.lifecycle.AndroidViewModel
  import androidx.lifecycle.LiveData
  import androidx.lifecycle.MutableLiveData
  import androidx.lifecycle.Transformations
  import com.example.expensetracker.database.ExpenseRepository
  import com.example.expensetracker.model.Expense
  import kotlinx.coroutines.CoroutineScope
  import kotlinx.coroutines.Dispatchers
  import kotlinx.coroutines.launch
  
  class TotalsViewModel(application: Application) : AndroidViewModel(application) {
  
      private val ioScope = CoroutineScope(Dispatchers.IO)
      private val expenseRepository = ExpenseRepository(application.applicationContext)
  
      var query = MutableLiveData&lt;String&gt;()
      val totals: LiveData&lt;List&lt;Expense&gt;&gt; = Transformations.switchMap(query, ::temp)
      private fun temp(query: String) = expenseRepository.getTotals(query)
  
      fun getTotals(queryString: String) = apply { query.value = queryString }
  
  
      fun insertExpense(expense: Expense) {
          ioScope.launch {
              expenseRepository.insertExpense(expense)
          }
      }
  
      fun deleteExpense(expense: Expense) {
          ioScope.launch {
              expenseRepository.deleteExpense(expense)
          }
      }
  }
  </code></pre>
  
  <p><strong>ExpenseDao:</strong></p>
  
  <pre><code>@Dao
  interface ExpenseDao {
  
      // sort by order they were added, newest on top
      @Query("SELECT * FROM expense_table ORDER BY id DESC LIMIT 15")
      fun getExpensesMain(): LiveData&lt;List&lt;Expense&gt;&gt;
  
      // get data for totals
      @Query("SELECT * FROM expense_table WHERE :queryString")
      fun getTotals(queryString: String): LiveData&lt;List&lt;Expense&gt;&gt;
  
  // Rest of the queries omitted
  </code></pre>
  
  <p><strong>ExpenseRepository:</strong></p>
  
  <pre><code>class ExpenseRepository(context: Context) {
  
      private var expenseDao: ExpenseDao
  
      init {
          val expenseRoomDatabase = ExpenseRoomDatabase.getDatabase(context)
          expenseDao = expenseRoomDatabase!!.expenseDao()
      }
  
      fun getExpensesMain(): LiveData&lt;List&lt;Expense&gt;&gt; {
          return expenseDao.getExpensesMain()
      }
  
      fun getTotals(queryString: String): LiveData&lt;List&lt;Expense&gt;&gt; {
          return expenseDao.getTotals(queryString)
      }
  
  // Code omitted
  </code></pre>
  
  <p><strong>ExpenseRoomDatabase:</strong></p>
  
  <pre><code>@Database(entities = [Expense::class], version = 1, exportSchema = false)
  abstract class ExpenseRoomDatabase : RoomDatabase() {
  
      abstract fun expenseDao(): ExpenseDao
  
      companion object {
          private const val DATABASE_NAME = "EXPENSE_DATABASE"
  
          @Volatile
          private var expenseRoomDatabaseInstance: ExpenseRoomDatabase? = null
  
          fun getDatabase(context: Context): ExpenseRoomDatabase? {
              if (expenseRoomDatabaseInstance == null) {
                  synchronized(ExpenseRoomDatabase::class.java) {
                      if (expenseRoomDatabaseInstance == null) {
                          expenseRoomDatabaseInstance = Room.databaseBuilder(
                              context.applicationContext,
                              ExpenseRoomDatabase::class.java, DATABASE_NAME
                          ).build()
                      }
                  }
              }
              return expenseRoomDatabaseInstance
          }
      }
  }
  </code></pre>
  
  <p><strong>ExpenseAdapterTotals:</strong></p>
  
  <pre><code>class ExpenseAdapterTotals(private val totals: MutableList&lt;Expense&gt;) : RecyclerView.Adapter&lt;ExpenseAdapterTotals.ViewHolder&gt;() {
  
      lateinit var context: Context
  
      override fun getItemCount(): Int {
          return totals.size
      }
  
      override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
          context = parent.context
          return ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_expense_totals, parent, false))
      }
  
      override fun onBindViewHolder(holder: ViewHolder, position: Int) {
          holder.bind(totals[position])
      }
  
      inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
          fun bind(totals: Expense) {
              itemView.tv_expense_totals.text = totals.expense
              itemView.tv_category_totals.text = totals.category
              itemView.tv_date_totals.text = totals.date
              itemView.tv_total_totals.text = totals.total.toString()
          }
      }
  }
  </code></pre>
  
  <p><strong>I have the following dependencies in my app build.gradle:</strong></p>
  
  <pre><code>    //Navigation
      implementation "androidx.navigation:navigation-fragment-ktx:2.0.0"
      implementation "androidx.navigation:navigation-ui-ktx:2.0.0"
  
  
      // ViewModel and LiveData
      def lifecycle_version = "2.1.0"
      implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
  
      // Room.
      def room_version = "2.1.0-rc01"
      implementation "androidx.room:room-runtime:$room_version"
      kapt "androidx.room:room-compiler:$room_version"
      implementation "androidx.room:room-ktx:$room_version"
  ....
  </code></pre>
  
  <p>So, this code is my most recent attempt but it has changed several times. I am not getting any error messages, but nothing is being shown either.</p>
  
  <p>My goal in a nutshell: When I click the button (btn_show), it should create the query string (which it does) and the RecyclerView in that fragment should update to show the desired results (which it doesn't). I assume the problem is somewhere between the ViewModel and the Fragment, but like I said, I am still a beginner, and this is the first time I am actually working on my purely own app.</p>
  
  <p>Thank you so much in advance for any help and tips, and feel free to ask if I left out anything you'd like to know. </p>