Reputation: 27
I am missing some basic coding knowledge here I think, I want to present value to the fragment by assigning the function to the variable in a viewModel. When I call the function directly, I get correct value. When I assign function to variable and pass the variable to the fragment it is always null, why?
View Model
class CartFragmentViewModel : ViewModel() {
private val repository = FirebaseCloud()
private val user = repository.getUserData()
val userCart = user?.switchMap {
repository.getProductsFromCart(it.cart)
}
private fun calculateCartValue(): Long? {
val list = userCart?.value
return list?.map { it.price!! }?.sum()
}
//val cartValue = userCart?.value?.sumOf { it.price!! } <- THIS will be null
val cartValue = calculateCartValue() <- THIS will be null
val cartSize = userCart?.value?.size <- THIS will be null
}
Fragment
class CartFragment : RootFragment(), OnProductClick, View.OnClickListener {
private lateinit var cartViewModel: CartFragmentViewModel
private lateinit var binding: FragmentCartBinding
private val cartAdapter = CartAdapter(this)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_cart,
container,
false
)
setAnimation()
cartViewModel = CartFragmentViewModel()
binding.buttonToCheckout.setOnClickListener(this)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.recyclerCart.apply {
layoutManager = LinearLayoutManager(requireContext())
adapter = cartAdapter
}
cartViewModel.userCart?.observe(viewLifecycleOwner, { list ->
cartAdapter.setCartProducts(list)
updateCart()
})
}
override fun onClick(view: View?) {
when (view) {
binding.buttonToCheckout -> {
navigateToCheckout(cartViewModel.cartValue.toString())
cartViewModel.sendProductEvent(
cartAdapter.cartList,
ProductEventType.CHECKOUT
)
}
}
}
override fun onProductClick(product: Product, position: Int) {
cartViewModel.removeFromCart(product)
cartAdapter.removeFromCart(product, position)
updateCart()
}
private fun updateCart() {
binding.textCartTotalValue.text = cartViewModel.cartValue.toString() <- NULL
binding.textCartQuantityValue.text = cartViewModel.cartSize.toString() <- NULL
}
}
Thanks!
Upvotes: 1
Views: 596
Reputation: 5980
It looks like userCart
is some sort of observable variable which initially holds a null value and then gets populated with the data from your repository after the network call (or something similar) completes.
The reason that all your variables are null are because you are declaring their value immediately, so by the time those statements get executed, the network call hasn't yet completed and userCart?.value
is null. However calling the calculateCartValue()
function later on in the code might yield a value if the fetch is complete.
Upvotes: 1