Search code examples
kotlinmvvmretrofitandroid-jetpack-composedagger-hilt

How to get the data from repository using viewmodel


When using Repository, I would like to get data from an API using ViewModel.

However, I do not understand how to configure the ViewModel in order to get the data. Let me know if I am doing this right by looking at my code. Additionally, a learning recommendation would be good, which is why I cannot figure it out. Does my basic coding skills need any improvement?

This is the AppModule

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    @Provides
    @Singleton
    fun providesPokemonRepository(
        api: MovieApiService
    ) = MovieRepository(api)

    @Singleton
    @Provides
    fun providesMovieApi(): MovieApiService {
        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(MovieApiService::class.java)
    }


}
This is the repository

class MovieRepository @Inject constructor(private val api: MovieApiService) {

    suspend fun getMovieLists(): Resource<List<MoviesItem>> {
        val response = try {
            api.getMovies()
        } catch (e: Exception) {
            return Resource.Error("An unknown error occurred")
        }
        return Resource.Success(response)
    }

}

This is the view model that I am trying to configure

@HiltViewModel
class MovieViewModel @Inject constructor(private val repository: MovieRepository) : ViewModel() {

    var response: List<MoviesItem> by mutableStateOf(listOf())
    val errorMessage: String by mutableStateOf("")
    val isLoading = mutableStateOf(false)

    fun getMovies() = viewModelScope.launch {
      val result = repository.getMovieLists()

    }
}

Solution

  • I guess response should require data in the UI. If you guess wrong, please ignore this answer. Otherwise, the response should be Ui as State.

    You have promoted List<MoviesItem> as a state to the ViewModel. The data is all in the ViewModel, so access and update of the data all happen in the ViewModel.

    If getMovies() is a function to update data, then you only need to put the result in response.

    Response is the state of Ui, and you have used MutableState to wrap it.

    var response by mutableStateOf(listOf<MoviesItem>())
        private set
     
    fun getMovies() = viewModelScope.launch {
         response = repository.getMovieLists()
    }
    

    In the Compose function, you can access your latest State through viewModel.response.

    You can also check the Android Compose documentation on ViewModel

    https://developer.android.com/jetpack/compose/state#viewmodel-state