Movies Database

Modifying the view model to use real data

First, we need to provide a MovieRepository for the view model to use.

We do this via constructor injection, passing it as a parameter to the constructor. When we create an instance of the view model, we'll need to pass one in.

Now that the view model knows about a repository, we can get data from that repository by delegation. Using MovieViewModel: MovieRepository by repository like this generates implementation functions and properties for those defined in MovieRepository that call the functions in the passed-in repository. This is similar to explicitly writing code like

class MovieViewModel(
    private val repository: MovieRepository,
): ViewModel() {
    val moviesFlow = repository.moviesFlow
    suspend fun getMovieWithCast(id: String) =
        repository.getMovieWithCast(id)

    suspend fun insert(actor: ActorDto) {
        repository.insert(actor)
    }
    ...
}

If any of the functions need to be more complex, you can override them.

Note

At this point the code will no longer compile, as we've broken the way movies are exposed to the UI.

Code Changes

CHANGED: /app/src/main/java/com/androidbyexample/movie/MovieViewModel.kt
package com.androidbyexample.movie

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import com.androidbyexample.movie.repository.ActorDtoimport com.androidbyexample.movie.repository.MovieRepositoryimport com.androidbyexample.movie.repository.MovieWithCastDtoimport com.androidbyexample.movie.screens.MovieList
import com.androidbyexample.movie.screens.Screen

//class MovieViewModel: ViewModel() {class MovieViewModel(
private val repository: MovieRepository,
): ViewModel(), MovieRepository by repository {
private var screenStack = listOf<Screen>(MovieList) set(value) { field = value
currentScreen = value.lastOrNull()
}
var currentScreen by mutableStateOf<Screen?>(MovieList) private set
fun pushScreen(screen: Screen) { screenStack = screenStack + screen } fun popScreen() { screenStack = screenStack.dropLast(1) }
// val movies: List<Movie> = listOf(// Movie("The Transporter", "Jason Statham kicks a guy in the face"),// Movie("Transporter 2", "Jason Statham kicks a bunch of guys in the face"),// Movie("Hobbs and Shaw", "Cars, Explosions and Stuff"),// Movie("Jumanji - Welcome to the Jungle", "The Rock smolders"),// )}