Concurrency with Kotlin Flow

Jun 5 2024 · Kotlin 1.9.20, Android 14, Android Studio Iguana

Lesson 03: Leverage Flow Operators

Filtering Operators Demo

Episode complete

Play next episode

Next
Transcript

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.

See forum comments
Cinema mode Download course materials from Github
Previous: Filtering Operators Next: Combining Operators