title: LiveData, MVVM and Repository Pattern
body: <p><strong><em>Is this a good approach or I've just found a nasty workaround?</em></strong></p>
  
  <p>I'm using <code>MediatorLiveData</code> class because seems useful to update the source of a <code>LiveData</code> object.</p>
  
  <p>I mean, the majority of tutorials that I've found on internet just use <code>Livedata</code> or <code>MutableLivedata</code> without a dynamic source, in example:</p>
  
  <pre><code>fun search(/*no input params*/): Call&lt;List&lt;Person&gt;&gt;
  </code></pre>
  
  <p>But in my case, I have the following web service that performs a search by name:</p>
  
  <pre><code>interface APIServidor {
      @GET("search")
      fun search(@Query("name") name: String): Call&lt;List&lt;Person&gt;&gt;
  
  }
  
  public class PeopleRepository {
  
  
      public LiveData&lt;List&lt;Person&gt;&gt; search(String name){
  
          final MutableLiveData&lt;List&lt;Person&gt;&gt; apiResponse = new MutableLiveData&lt;&gt;();
          Call&lt;List&lt;Person&gt;&gt; call = RetrofitService.Companion.getInstance().getApiServer().search(name);
          call.enqueue(new Callback&lt;List&lt;Person&gt;&gt;() {
              @Override
              public void onResponse(@NonNull Call&lt;List&lt;Person&gt;&gt; call, @NonNull Response&lt;List&lt;Person&gt;&gt; response) {
                  if (response.isSuccessful()) {
                      apiResponse.postValue(response.body());
                  }
              }
  
              @Override
              public void onFailure(@NonNull Call&lt;List&lt;Person&gt;&gt; call, @NonNull Throwable t) {
                  apiResponse.postValue(null);
              }
          });
  
          return apiResponse;
      }
  }
  </code></pre>
  
  <p>Then in the viewmodel class I'm adding source per new request.</p>
  
  <pre><code>public class SearchViewModel extends ViewModel {
  
      private MediatorLiveData&lt;List&lt;Person&gt;&gt; mApiResponse;
      private PeopleRepository mApiRepo;
  
      public SearchViewModel() {
          mApiResponse = new MediatorLiveData&lt;&gt;();
          mApiRepo = new PeopleRepository();
      }
  
      public LiveData&lt;List&lt;Person&gt;&gt; getPlayers() {
          return mApiResponse;
      }
  
      public void performSearch(String name){
          mApiResponse.addSource(mApiRepo.search(name), new Observer&lt;List&lt;Person&gt;&gt;() {
              @Override
              public void onChanged(List&lt;Person&gt; apiResponse)            {
                  mApiResponse.setValue(apiResponse);
              }
          });
      }
  }
  </code></pre>
  
  <p>Activity</p>
  
  <pre><code>bt_search.setOnClickListener {
      val player_name = et_player.text.toString()
      viewModel.performSearch(player_name)
  }
  </code></pre>
  
  <h1>Project scope</h1>
  
  <p>I'm in a personal project</p>
  
  <h1>Goals</h1>
  
  <p>Use MVVM + Live data + Repository pattern</p>
  
  <h1>Problem</h1>
  
  <p>I've only found tutorials with a simple approach: observe a <code>LiveData</code> object that access to a <code>repository</code> object and fetch data only once. </p>
  
  <p>In example: Fetch all people (<code>select * from people</code>) from web service.</p>
  
  <p>My case: Fetch people that mach a name (<code>select * from people where name=?</code>) from web service.</p>
  
  <p><a href="https://medium.com/@elye.project/kotlin-and-retrofit-2-tutorial-with-working-codes-333a4422a890" rel="nofollow noreferrer">https://medium.com/@elye.project/kotlin-and-retrofit-2-tutorial-with-working-codes-333a4422a890</a>
  <a href="https://medium.com/@sriramr083/error-handling-in-retrofit2-in-mvvm-repository-pattern-a9c13c8f3995" rel="nofollow noreferrer">https://medium.com/@sriramr083/error-handling-in-retrofit2-in-mvvm-repository-pattern-a9c13c8f3995</a></p>
  
  <h1>Doubts</h1>
  
  <p>Is a good idea use <code>MediatorLiveData</code> class to <code>merge</code> all requests took from user input?</p>
  
  <p>Should I use <code>MutableLiveData</code> and change the <code>repository</code> class and use a custom clousure?</p>
  
  <p>Is there a better approach? </p>