'Kotlin read from room database in fragment

I write an application with room database and I have a problem with reading data and use it in the mine thread.

consider tables as those:

Table1

| ID |  Name  |
| -- | ------ |
| 1  | first  |
| 2  | second |

Table2

| ID | Name |  description  | table1_id|
|--- | ---- | ------------- |----------|
| 1  | test | not important |     2    |
| 2  | test | not important |     1    |

I have no problem to display information about object from table2 since it is passed to the fragment, but when I try to get Name by ID from table1 I am unable to do so. I searched for information, but nothing I've found helped me.

My code:

private var _binding: FragmentXUpdateBinding? = null
private val binding get() = _binding!!

private lateinit var mXViewModel: XViewModel
private lateinit var mXTypeViewModel: XTypeViewModel
private val args by navArgs<XUpdateFragmentArgs>()

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    _binding = FragmentXUpdateBinding.inflate(inflater, container, false)
    mXViewModel = ViewModelProvider(this)[XViewModel::class.java]
    mXTypeViewModel = ViewModelProvider(this)[XTypeViewModel::class.java]
    setHasOptionsMenu(true)

        val XType = getXTypeName(args.currentX.X_type_id)
        binding.XTypeText.text = XType


    binding.etXName.setText(args.currentX.name)
    binding.etXDescription.setText(args.currentX.description)

    binding.buttonUpdateX.setOnClickListener {
        updateItem()
        findNavController().navigate(my.food.R.id.action_XUpdateFragment_to_XListFragment)
    }

    return binding.root
}

private fun getXTypeName(id: Int): String {
  var XTypeString = ""
  mXTypeViewModel.readAllData.observe(viewLifecycleOwner) { type ->
      type?.forEach {
          if (it.id == id) {
              XTypeString = it.name
          }
      }
  }
  return XTypeString   //it returns "" since database thread is still ongoing
}

Please note the comment in the second from the end line.

What's the solution to my headache? THANKS!!!!



Solution 1:[1]

The problem is that you are trying to retrieve XTypeString before your asynchronous task(readAllData from ViewModel) has completed. You should move the binding of XTypeText inside observe, as below. Note the change in function signature for bindXTypeText().

private fun bindXTypeText(id: Int) {
  var XTypeString = ""
  mXTypeViewModel.readAllData.observe(viewLifecycleOwner) { type ->
      type?.forEach {
          if (it.id == id) {
              XTypeString = it.name
          }
      }

      binding.XTypeText.text = XTypeString //moved the assignment of XtypeText here.
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 HaroldSer