Kotlin Jetpack Compose Retrofit View Model

108 Views Asked by At

I have the below code and I'm inquiring if this View Model is proper or if I'm missing anything. My goal is a View Model that stores HTTP request data and makes the HTTP requests, with custom headers.

I'm also having trouble with handling arrays of data classes as I have an error in the second line of the view model. I would also like to be able to get and set data from another view model from the view model below (I tried implementing the first line of the View Model but it didn't work).

Interface:

interface ApiInterface {
    @GET("/data")
    suspend fun loadData(authKey: String): Response<ArrayOfDataClassExample>
}

Retrofit Instance:

object RetrofitInstance {

    private val client = OkHttpClient.Builder().apply {
        addInterceptor(Interceptor())
    }.build()

    val api : ApiInterface by lazy {
        Retrofit.Builder()
            .baseUrl(Util.Base)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(ApiInterface::class.java)
    }
}

DataClass:

data class DataClassExample (
    val id: Int,
    val accountID: Int
)

data class ArrayOfDataClassExample (
    val data: Array<DataClassExample>
)

View Model:

class ServerDataViewModel(application: Application) : AndroidViewModel(application) {
    val accountType by preferencesViewModel.accountType.observeAsState("")
    var data: ArrayOfDataClassExample = ArrayOfDataClassExample(arrayOf(DataClassExample))

    @OptIn(DelicateCoroutinesApi::class)
    suspend fun getData() {
        GlobalScope.launch(Dispatchers.IO) {
            val response = try {
                RetrofitInstance.api.loadEntries(authKey = "")
            } catch (e: HttpException) {
                print(e.message)
                return@launch
            } catch (e: IOException) {
                print(e.message)
                return@launch
            }

            if (response.isSuccessful && response.body() != null) {
                withContext(Dispatchers.Main) {
                    data = response.body()!!
                }
            }
        }
    }
}
1

There are 1 best solutions below

1
MexiCano On

Try this:

class ServerDataViewModel(application: Application) : AndroidViewModel(application) {
    private val _data = MutableLiveData<ArrayOfDataClassExample>()
    val data: LiveData<ArrayOfDataClassExample> = _data

    fun getData(authKey: String) {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                val response = RetrofitInstance.api.loadData(authKey)
                if (response.isSuccessful && response.body() != null) {
                    _data.postValue(response.body())
                } else {
                }
            } catch (e: HttpException) {
            } catch (e: IOException) {
            }
        }
    }
}

and:

object RetrofitInstance {

    private val client = OkHttpClient.Builder().apply {
        addInterceptor { chain ->
            val newRequest = chain.request().newBuilder()
                .addHeader("Authorization", "Bearer your_auth_key_here")
                .build()
            chain.proceed(newRequest)
        }
    }.build()

    val api: ApiInterface by lazy {
        Retrofit.Builder()
            .baseUrl(Util.Base)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(ApiInterface::class.java)
    }
}