title: Observing LiveData in ViewModel best practices
body: <p>I'm seeking the best way to observe data in <code>ViewModel</code>.</p>
  <p>I'm using MVVM + DataBinding.</p>
  <p><strong>Repository:</strong></p>
  <pre><code>private val data = MutableLiveData&lt;String&gt;()
  
  suspend fun getData(): LiveData&lt;String&gt; {
          return withContext(IO) {
              val response = apiRequest { api.getData() }
              data.postValue(response)
              data
          }
      }
  </code></pre>
  <p>It requests data from server and returns a live data. ViewModel must observe the data changes.</p>
  <p><strong>ViewModel:</strong></p>
  <pre><code>    suspend fun getData() {
          val data = repository.getData()
          MediatorLiveData&lt;String&gt;().apply {
              addSource(data) {
                  gotData(it)
                  removeSource(data)
              }
              observeForever { }
          }
      }
  
      private fun gotData(data: String) {
          //use data
      }
  </code></pre>
  <p>ViewModel uses a <code>MediatorLiveData</code> to observe changes of the <code>LiveData</code> that comes from repository. I've added the data as a source to observe changes and remove it after it triggers to prevent firing events multiple times when I get data multiple times. And there must be a fake observer to <code>MediatorLiveData</code> so the onChange method of the <code>MediatorLiveData</code> triggers.</p>
  <p>Let's say that I just need the data to hide/show a view (or even fill data to my recyclerview's adaper). Then I just call the below code and use an Observable and DataBinding like this:</p>
  <pre><code>val adapter: ObservableField&lt;DataAdapter&gt; = ObservableField()
  val recyclerviewVisibility: ObservableField&lt;Int&gt; = ObservableField(View.GONE)
  ...
  ...
  recyclerviewVisibility.set(View.VISIBLE)
  adapter.set(DataAdapter(dataList))
  </code></pre>
  <p>So I don't need to pass the data to <code>Fragment</code> or <code>Activity</code> to use the <code>viewLifecycleOwner</code>.
  I also cannot use <code>observeForever</code> in <code>ViewModel</code> because it may fire onChange method multiple times in some situations.</p>
  <p>Is there any better approach to get and observe data in <code>ViewModel</code>?</p>
  <hr />
  <p><strong>Solution :</strong></p>
  <p>I've found out that the best way to reach my goal is to get the data from repository without using <code>LiveData</code>:</p>
  <p><strong>Repository</strong></p>
  <pre><code>suspend fun getData() : String{
      return  apiRequest { api.getData() }
  }
  </code></pre>
  <p><strong>ViewModel</strong></p>
  <pre><code>suspend fun getData(){
     val data = repository.getData()
      gotData(data)
  }
  
  fun gotData(data: String) {
      //use data
  }
  </code></pre>
  <p>It's much simpler now.</p>
  <hr />
  <p><strong>Bonus:</strong></p>
  <p>extension:</p>
  <pre><code>fun &lt;T : Any&gt; ViewModel.request(request: suspend () -&gt; (T), result: (T) -&gt; (Unit) = {}) {
      viewModelScope.launch {
          result(request())
      }
  }
  </code></pre>
  <p>usage:</p>
  <pre><code>request({request.getData()}) {
      //use data
  }
  </code></pre>