title: How to observe LiveData from Repository?
body: <p>I'd like to get a User from my Room database using the Repository, and then observing it in the OverviewFragment.</p>
  
  <p><em>What I tried:</em></p>
  
  <ul>
  <li><p>using an Observer in the fragment, but I got a NullPointerException.</p></li>
  <li><p>using <code>@{overviewViewModel.user.email}</code> in fragment_overview.xml: the application runs but nothing is displayed.</p></li>
  <li><p>Unit Testing and Instrumented Testing with a FakeRepository. The tests pass and the data are displayed.</p></li>
  </ul>
  
  <p><em>What I use:</em></p>
  
  <ul>
  <li><p>Android Studio (up to date)</p></li>
  <li><p>Kotlin</p></li>
  <li><p>MVVM architecture</p></li>
  <li><p>Repository pattern linked to a Room database</p></li>
  <li><p>Constructor dependency injection (for the viewmodels)</p></li>
  <li><p><a href="https://proandroiddev.com/why-service-locator-is-so-unpopular-bbe8678be72c" rel="nofollow noreferrer">ServiceLocator</a> pattern for testing</p></li>
  </ul>
  
  <p><em>User Flow (Navigation)</em></p>
  
  <p>The User opens the app, fills a form and clicks the registration button in the RegistrationFragment, then navigates to the OverviewFragment, where his data (Email, Password) are displayed.</p>
  
  <p><strong>RegistrationViewModel:</strong></p>
  
  <pre><code>class RegistrationViewModel(private val repository: IUserRepository) : ViewModel() {
  
      private var viewModelJob = Job()
      private val uiScope = CoroutineScope(Dispatchers.Main +  viewModelJob)
  
      private val _user = MutableLiveData&lt;User&gt;()
  
      val user: LiveData&lt;User&gt;
          get() = _user
  
      val email = MutableLiveData&lt;String&gt;()
      val password = MutableLiveData&lt;String&gt;()
  
      [...]
  
      fun onRegister() {
  
          val userEmail = email.value.toString()
          val userPassword = password.value.toString()
  
          registerUser(User(userEmail, userPassword))
      }
  
      private fun registerUser(newUser: User) = uiScope.launch {
          repository.registerUser(newUser)
      }
  
      [...]
  }
  </code></pre>
  
  <p><strong>OverviewViewModel</strong></p>
  
  <pre><code>class OverviewViewModel(val database: UserDatabaseDao,
                          private val userRepository: IUserRepository
  ) : ViewModel() {
  
      private val _user = MutableLiveData&lt;User&gt;()
  
      val user: LiveData&lt;User&gt;
          get() = _user
  
      init {
          getUser()
      }
  
      private fun getUser() {
          runBlocking {_user.value = userRepository.getUser().value }
      }
  </code></pre>
  
  <p><strong>OverviewFragment:</strong></p>
  
  <pre><code>class OverviewFragment : Fragment() {
  
  [...]
          overviewViewModel.user.observe(this, Observer {
                  binding.apply {
                      textview.text = overviewViewModel.user.value!!.email
                      textview2.text = overviewViewModel.user.value!!.password
                  }
          })
          return binding.root
      }
  }
  </code></pre>
  
  <p><strong>Repository:</strong></p>
  
  <pre><code>class UserRepository(private val dataSource: UserDatabaseDao,
                       private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO) :
      IUserRepository {
  
      override suspend fun registerUser(user: User) = withContext(ioDispatcher) {
          dataSource.insert(user)
      }
  
      override suspend fun getUser(): LiveData&lt;User?&gt; = withContext(ioDispatcher) {
          return@withContext dataSource.getUser()
      }
  
      override suspend fun getUser(email: String): LiveData&lt;User?&gt; = withContext(ioDispatcher) {
          return@withContext dataSource.getUser(email)
      }
  }
  </code></pre>
  
  <p><strong>DatabaseDao:</strong></p>
  
  <pre><code>@Dao
  interface UserDatabaseDao {
  
      @Insert
      fun insert(user: User)
  
      @Query("SELECT * from user_table WHERE email = :key")
      fun getUser(key: String): LiveData&lt;User?&gt;
  
      @Query("SELECT * from user_table")
      fun getUser(): LiveData&lt;User?&gt;
  
      @Query("SELECT * from user_table")
      fun getAllUsers(): LiveData&lt;List&lt;User&gt;&gt;
  
  }
  </code></pre>
  
  <p>Note: there's only one user in the database, the one that fills the form in the RegistrationFragment.</p>