0

I am trying to create a ViewModel in my Kotlin app, but I am getting the following error: java.lang.RuntimeException: Cannot create an instance of class com.ri.movieto.presentation.home.HomeViewModel. Also, I am using Hilt.

And here is the code for my HomeFragment:

@AndroidEntryPoint
class HomeFragment : Fragment() {

    private var _binding: FragmentHomeBinding? = null

    private val homeViewModel: HomeViewModel by viewModels()

    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        _binding = FragmentHomeBinding.inflate(inflater, container, false)

        contentLayout = binding.contentLayout
        dataLoading = binding.dataLoading

        subscribeToObservables()

        return binding.root
    }

    private fun subscribeToObservables() {
        lifecycleScope.launchWhenStarted {
            homeViewModel.state.collectLatest {
                Log.e("++++", it.response?.page.toString())
            }
        }
    }
}

Here is the code for my HomeViewModel:

@HiltViewModel
class HomeViewModel @Inject constructor(
    private val getTrendingMoviesUseCase: GetTrendingMoviesUseCase
) : ViewModel() {

    private val _state = MutableStateFlow(TrendingMoviesState())
    val state = _state.asStateFlow()

    init {
        getTrendingMovies()
    }

    private fun getTrendingMovies() {
        getTrendingMoviesUseCase().onEach { result ->
            when (result) {
                is Resource.Success -> {
                    _state.value = TrendingMoviesState(response = result.data)
                }
                is Resource.Error -> {
                    _state.value =
                        TrendingMoviesState(error = result.message ?: "An unexpected error occurred")
                }
                is Resource.Loading -> {
                    _state.value = TrendingMoviesState(isLoading = true)
                }
            }
        }
    }
}

GetTrendingMoviesUseCase.kt:

class GetTrendingMoviesUseCase @Inject constructor(
    private val repository: MovieRepository,
    private val movieResponseDtoToDomain: MovieResponseDtoToDomain
) {
    operator fun invoke(): Flow<Resource<MovieResponse>> = flow {
        try {
            emit(Resource.Loading())
            val movieResponseDto = repository.getTrendingMovies()
            val movieResponse = movieResponseDtoToDomain.mapFrom(movieResponseDto)
            emit(Resource.Success(movieResponse))
        } catch (e: HttpException) {
            emit(Resource.Error(e.localizedMessage ?: "Beklenmeyen bir hata oluştu"))
        } catch (e: IOException) {
            emit(Resource.Error("Lütfen internet bağlantınızı kontrol edin"))
        }
    }
}

MovieResponseDtoToDomain.kt:

@Singleton
class MovieResponseDtoToDomain @Inject constructor(private val itemDecider: MovieItemDecider) :
    Mapper<MovieResponseDto, MovieResponse> {
    override fun mapFrom(input: MovieResponseDto): MovieResponse {
        return MovieResponse(
            page = input.page,
            movies = input.results.map { movie ->
                MovieResponse.Movie(
                    release_year = itemDecider.provideReleaseYear(movie.release_date),
                    poster_path = itemDecider.providePosterPath(movie.poster_path),
                    backdrop_path = itemDecider.provideBackdropPath(movie.backdrop_path),
                    vote_average = itemDecider.provideRoundedAverage(movie.vote_average),
                    title = movie.title,
                    id = movie.id,
                    video = movie.video,
                    release_date = movie.release_date,
                    overview = movie.overview,
                    genre_ids = movie.genre_ids
                )
            },
            total_pages = input.total_pages,
            total_results = input.total_results
        )
    }

}
İbrahim Uyar
  • 87
  • 1
  • 6
  • Can you share how you provide "GetTrendingMoviesUseCase" into ViewModel? – skywall Feb 19 '23 at 11:26
  • Hello @skywall , I have attached the files you requested. Also, the error occurs inside the subscribeToObservables function in the Fragment. – İbrahim Uyar Feb 19 '23 at 11:33
  • I don't see "subscribeToObservables" being called anywhere. Also, do you observe the same error when you remove all usages of the ViewModel variable from Fragment? – skywall Feb 19 '23 at 11:59
  • Sorry, I spelled it wrong here. Normally I called. Also, if I delete the inside of the subscribeToObservables function, the error will not occur. @skywall – İbrahim Uyar Feb 19 '23 at 12:07
  • One of the last possible issues is "MovieRepository". How do you provide it into UseCase? – skywall Feb 19 '23 at 12:28
  • 1
    Thank you @skywall . In fact, there was a lot that was missing. I fixed the problem and now it works as I want. – İbrahim Uyar Feb 19 '23 at 19:13

0 Answers0