I am calling an API using retrofit and the it is returning null.
Model class
data class Employee(
val id: Int,
val employee_name: String,
val employee_salary: Int,
val employee_age: Int,
val profile_image: String
)
ViewModel class
package com.example.myproject.ViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.myproject.Service.ApiService
import com.example.myproject.model.Employee
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class EmployeeViewModel : ViewModel() {
private val _data = MutableStateFlow<List<Employee>?>(emptyList())
val data: StateFlow<List<Employee>?> = _data
init {
fetchData()
}
private fun fetchData() {
viewModelScope.launch {
try {
val apiService = Retrofit.Builder()
.baseUrl("https://dummy.restapiexample.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
val response = apiService.getEmployees()
_data.value = response
} catch (e: Exception) {
// Handle error
// _data.value = emptyList()
e.printStackTrace()
}
}
}
}
Api service interface
interface ApiService {
@GET("/api/v1/employees")
suspend fun getEmployees(): List<Employee>
}
MainActivity.kt
package com.example.myproject
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Card
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import com.example.myproject.ui.theme.MyProjectTheme
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.myproject.ViewModel.EmployeeViewModel
import com.example.myproject.model.Employee
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyProjectTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
val viewModel: EmployeeViewModel = viewModel()
EmployeeScreen(viewModel)
}
}
}
}
@Composable
fun EmployeeScreen(viewModel: EmployeeViewModel) {
val data by viewModel.data.collectAsState(initial = emptyList())
if (data?.isEmpty() == true) {
CircularProgressIndicator()
} else {
LazyColumn {
items(data!!) { employee ->
EmployeeListItem(employee)
}
}
}
}
@Composable
fun EmployeeListItem(employee: Employee) {
Card {
Column {
Text(text = employee.employee_name)
Text(text = "Salary: ${employee.employee_salary}")
Text(text = "Age: ${employee.employee_age}")
// Add image view if profile_image is available
}
}
}
}
It is returning me null data with no warning I have also added the appropriate dependencies for retrofit, gsonconverter and okhttp but still the response is blank. Help appreciated!
I believe, the thing is. That api does not just return a list of employees. You can check yourself at https://dummy.restapiexample.com/api/v1/employees . It returns an object with the fields status
, data
and message
. That data
is the list of employees. So you need a class that represents the full response. Like
data class EmployeeResponse(
val status: String,
val data: List<Employee>,
val message: String
)
And fix the interface to use this class
interface ApiService {
@GET("/api/v1/employees")
suspend fun getEmployees(): EmployeeResponse
}
and
_data.value = response.data