Home > Net >  Kotlin read from room database in fragment
Kotlin read from room database in fragment

Time:05-15

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!!!!

CodePudding user response:

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.
  }
}
  • Related