In this demo, you’ll see how to use the filter operator you covered in the previous lesson and also how to use the
flatMapLatest operator from the transforming operators’ lesson.
Open CategoryViewModel.kt. Right now, it’s mostly empty. You won’t complete it in this demo, but you’ll add the necessary functions that you’ll use in the final demo.
This ViewModel is responsible for preparing the CategoryScreenViewState. That view state contains the
MovieCategoryViewState object and a list of MovieViewState objects. You’ll focus on preparing those two objects.
First, add the first function:
private fun category(categoryId: String): Flow<MovieCategoryViewState> =
movieRepository.categories()
.filter { category -> category.id == categoryId }
.map { category -> MovieCategoryViewState(category.id, category.name) }
Add the necessary import:
import kotlinx.coroutines.flow.*
This function filters the flow of MovieCategory objects for the specific category. In the end, it transforms that
object into a MovieCategoryViewState object.
Next, add the second function:
@OptIn(ExperimentalCoroutinesApi::class)
private fun moviesForCategory(categoryId: String): Flow<List<MovieViewState>> =
movieRepository.categories()
.filter { it.id == categoryId }
.flatMapLatest { movieCategory -> movieRepository.fetchMoviesForCategory(movieCategory.name) }
.map { movies ->
movies.map { movie ->
val imageRes = movieRepository.fetchMovieImage(movieId = movie.id)
MovieViewState(movie.id, movie.title, "", imageRes)
}
}
Add the necessary import:
import kotlinx.coroutines.ExperimentalCoroutinesApi
This function is responsible for creating a flow of the MovieViewState list. It uses the filter operator to get a specific
category, and then it uses flatMapLatest to create a new flow that emits the movie list. Lastly, it maps the list of
Movie objects into the list of MovieViewState objects.
The last method will give you an error, to fix it, add the following function to the MovieRepository.kt:
fun fetchMoviesForCategory(categoryName: String): Flow<List<Movie>> = flow {
val movies = movieService.fetchMoviesForCategory(categoryName)
emit(movies)
}
This ends the demo. In the next lesson, you’ll learn about combining operators, which you’ll use in the last demo to complete this ViewModel.