0

How to pass my viewmodel to a class that does not extend activity I'm calling my viewmodel like this: in my EntryAbstract class where am I going wrong

val FrutasViewModel = ViewModelProvider.NewInstanceFactory().create(FrutasViewModel::class.java)

     FrutasViewModel.frutaData.value.forEach { item->
            itens.add(ShoppingCart
            (id=item.id,photo=item.photo,
                    name=item.name,quantidade=item.quantidade
                    ,categoria = item.categoria,descricao = item.descricao
                    ,unidade=item.unidade,kilo = item.kilo

            ))
        }

my viewmodel:

package com.example.quitanda.models

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class FrutasViewModel(
    private val frutasServices: Services,
):ViewModel() {

    private val _frutasData: MutableStateFlow<List<ShoppingCart>> = MutableStateFlow<List<ShoppingCart>>(listOf<ShoppingCart>(ShoppingCart()))
    val frutaData: StateFlow<List<ShoppingCart>>
    get() = _frutasData

    fun getFrutas(){

        viewModelScope.launch {
            try {
                val frutas = frutasServices.getFruta()
                _frutasData.value = frutas
            }catch (e:Exception){
                Log.d("Service error",e.toString())
            }
        }
    }
}

My service:

package com.example.quitanda.models

import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.GET


interface Services {

    @GET("/category/7")
    suspend fun  getFruta(
         //@Query("apikey")
        //apikey:String = "333b4285"
    ): List<ShoppingCart>


}

val retrofit: Retrofit = Retrofit.Builder()
    .baseUrl("http://localhost:4000/")
    .addConverterFactory(MoshiConverterFactory.create())
    .build()

val frutasServices: Services = retrofit.create(Services::class.java)

My model:

package com.example.quitanda.models

import android.os.Parcelable
import com.squareup.moshi.Json
import kotlinx.parcelize.Parcelize

@Parcelize
data class ShoppingCart(
    var count:Int=0,
    @field:Json(name="product_title")
    var name:String="",
    @field:Json(name="product_id")
    var id:Int=0,
    @field:Json(name="photo_photo")
    var photo:String="",
    @field:Json(name="product_quant")
    var quantidade:Int=0,
    @field:Json(name="category_name")
    var categoria:String="",
    @field:Json(name="product_description")
    var descricao:String="",
    @field:Json(name="product_price_un")
    var unidade:String="",
    @field:Json(name="product_price_kg")
    var kilo:String="",
    var tipos:String=""): Parcelable

When I try to run my code it gives the following error Does anyone have any idea how to fix this who can help I am grateful

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.quitanda, PID: 11031
    java.lang.RuntimeException: Cannot create an instance of class com.example.quitanda.models.FrutasViewModel
        
Rafael Souza
  • 1,143
  • 2
  • 13
  • 29
  • What you are trying is not recommended practice, check this answer: https://stackoverflow.com/a/51007347/4704327, it might help you – Anand May 23 '21 at 06:43

1 Answers1

1

I wouldn't recommend doing what you're trying to achieve, because what Android did, is that they've abstracted how viewmodels are scoped, to give you developers the power to easily handle things like orientation-change.

In practice this means, that android views, such as Activity/Fragment implement a ViewModelStoreOwner which contains a ViewModelStore, which handles the scoping and retrieves the correct ViewModel instance based on context.

TL;DR: If you want an android arch.viewmodel then create it in your Activity/Fragment and pass it to the EntryAbstract, though chances are you just need some of the data, which could be set individually for better separation of concerns

Róbert Nagy
  • 6,720
  • 26
  • 45