title: How to convert normal data(returned from room) to LiveData on ViewModel layer
body: <p>I am using the clean architecture with MVVM pattern so the room part goes into the data layer and I'm returning observables from there to domain layer and using them in presentation layer by wrapping them in a LiveData.
  Now, the problem is that after insertion/deletion/update the list is not getting updated immediately in UI.</p>
  
  <p>Viewmodel in Presentation Layer:   </p>
  
  <pre><code>public class WordViewModel extends BaseViewModel&lt;WordNavigator&gt; {
  
  //get all the use cases here
  private GetAllWords getAllWords;
  private InsertWord insertWord;
  private DeleteThisWord deleteThisWord;
  private UpdateThisWord updateThisWord;
  private GetTheIndexOfTopWord getTheIndexOfTopWord;
  
  //data
  public MutableLiveData&lt;List&lt;Word&gt;&gt; allWords;
  
  
  public WordViewModel(GetAllWords getAllWords, InsertWord insertWord, DeleteThisWord deleteThisWord, UpdateThisWord updateThisWord, GetTheIndexOfTopWord getTheIndexOfTopWord) {
      this.getAllWords = getAllWords;
      this.insertWord = insertWord;
      this.deleteThisWord = deleteThisWord;
      this.updateThisWord = updateThisWord;
      this.getTheIndexOfTopWord = getTheIndexOfTopWord;
  }
  
  public void getAllWords() {
      getAllWords.execute(new DisposableObserver&lt;List&lt;Word&gt;&gt;() {
          @Override
          public void onNext(List&lt;Word&gt; words) {
              allWords.setValue(words);
          }
  
          @Override
          public void onError(Throwable e) {
  
          }
  
          @Override
          public void onComplete() {
  
          }
      }, GetAllWords.Params.getAllWords());
  }
  
  
  public void insertWord(Word word) {
      insertWord.execute(new DisposableObserver&lt;Boolean&gt;() {
          @Override
          public void onNext(Boolean aBoolean) {
              if (aBoolean)
                  Log.e("ganesh", "word inserted successfully!!!");
          }
  
          @Override
          public void onError(Throwable e) {
              e.printStackTrace();
          }
  
          @Override
          public void onComplete() {
  
          }
      }, InsertWord.Params.insertWord(word));
  
  }
  
  public void getTheIndexOfTopWord(final String action) {
      getTheIndexOfTopWord.execute(new DisposableObserver&lt;Word&gt;() {
          @Override
          public void onNext(Word word) {
              if (word != null)
                  getNavigator().updateTopIndex(word.getWordId(), action);
          }
  
          @Override
          public void onError(Throwable e) {
              e.printStackTrace();
          }
  
          @Override
          public void onComplete() {
  
          }
      }, GetTheIndexOfTopWord.Params.getTheIndexOfTopWord());
  }
  
  public void deleteThisWord(int wordId) {
      deleteThisWord.execute(new DisposableObserver&lt;Boolean&gt;() {
          @Override
          public void onNext(Boolean aBoolean) {
              if (aBoolean)
                  Log.e("ganesh", "word deleted successfully!!!");
          }
  
          @Override
          public void onError(Throwable e) {
              e.printStackTrace();
          }
  
          @Override
          public void onComplete() {
  
          }
      }, DeleteThisWord.Params.deleteThisWord(wordId));
  }
  
  public void updateThisWord(int wordId, String newWord) {
      updateThisWord.execute(new DisposableObserver&lt;Boolean&gt;() {
          @Override
          public void onNext(Boolean aBoolean) {
              if (aBoolean)
                  Log.e("ganesh", "word updated successfully!!!");
          }
  
          @Override
          public void onError(Throwable e) {
              e.printStackTrace();
          }
  
          @Override
          public void onComplete() {
  
          }
      }, UpdateThisWord.Params.updateThisWord(wordId, newWord));
  }
  
  public MutableLiveData&lt;List&lt;Word&gt;&gt; getWords() {
      if (allWords == null) {
          allWords = new MutableLiveData&lt;&gt;();
      }
      return allWords;
  }
  
  @Override
  protected void onCleared() {
      super.onCleared();
  
      if (getAllWords != null)
          getAllWords = null;
      if (deleteThisWord != null)
          deleteThisWord = null;
      if (insertWord != null)
          insertWord = null;
      if (updateThisWord != null)
          updateThisWord = null;
      if (getTheIndexOfTopWord != null)
          getTheIndexOfTopWord = null;
  
  }
  }
  </code></pre>
  
  <p>DAO in Data Layer:</p>
  
  <pre><code>@Dao
  public interface WordDao {
  @Insert
  void insertThisWord(Word word);
  
  @Query("delete from word_table")
  void deleteAll();
  
  @Query("select * from word_table order by word_id asc")
  List&lt;Word&gt; getAllWords();
  
  @Query("delete from word_table where word_id = :wordId")
  void deleteThisWord(int wordId);
  
  @Query("update word_table set word = :newWord where word_id = :wordId")
  void updateThisWord(int wordId, String newWord);
  
  @Query("select * from word_table order by word_id asc limit 1")
  Word getTheIndexOfTopWord();
  }
  </code></pre>
  
  <p>Repository in Data Layer:</p>
  
  <pre><code>public class WordRepositoryImpl implements WordRepository {
  
  private ApiInterface apiInterface;
  private SharedPreferenceHelper sharedPreferenceHelper;
  private Context context;
  
  private WordDao wordDao;
  private WordRoomDatabase db;
  
  public WordRepositoryImpl(ApiInterface apiInterface, SharedPreferenceHelper sharedPreferenceHelper, WordRoomDatabase db, Context context) {
      this.apiInterface = apiInterface;
      this.sharedPreferenceHelper = sharedPreferenceHelper;
      this.context = context;
      this.db = db;
      wordDao = db.wordDao();
  }
  
  
  @Override
  public Observable&lt;Integer&gt; sum(final int a, final int b) {
      return Observable.fromCallable(new Callable&lt;Integer&gt;() {
          @Override
          public Integer call() throws Exception {
              return (a + b);
          }
      });
  }
  
  @Override
  public Observable&lt;List&lt;Word&gt;&gt; getAllWords() {
      return Observable.fromCallable(new Callable&lt;List&lt;Word&gt;&gt;() {
          @Override
          public List&lt;Word&gt; call() throws Exception {
              List&lt;Word&gt; list = new ArrayList&lt;&gt;();
              List&lt;com.example.data.models.Word&gt; listWords = db.wordDao().getAllWords();
              for (com.example.data.models.Word item : listWords) {
                  list.add(new Word(item.getWordId(), item.getWord(), item.getWordLength()));
              }
              return list;
          }
      });
  }
  
  @Override
  public Observable&lt;Boolean&gt; insertThisWord(final Word word) {
      return Observable.fromCallable(new Callable&lt;Boolean&gt;() {
          @Override
          public Boolean call() throws Exception {
              com.example.data.models.Word item = new com.example.data.models.Word(word.getWord(), word.getWordLength());
              db.wordDao().insertThisWord(item);
              return true;
          }
      });
  }
  
  @Override
  public Observable&lt;Boolean&gt; deleteThisWord(final int wordId) {
      return Observable.fromCallable(new Callable&lt;Boolean&gt;() {
          @Override
          public Boolean call() throws Exception {
              db.wordDao().deleteThisWord(wordId);
              return true;
          }
      });
  }
  
  @Override
  public Observable&lt;Boolean&gt; updateThisWord(final int wordId, final String newWord) {
      return Observable.fromCallable(new Callable&lt;Boolean&gt;() {
          @Override
          public Boolean call() throws Exception {
              db.wordDao().updateThisWord(wordId, newWord);
              return true;
          }
      });
  }
  
  @Override
  public Observable&lt;Word&gt; getTheIndexOfTopWord() {
      return Observable.fromCallable(new Callable&lt;Word&gt;() {
          @Override
          public Word call() throws Exception {
              com.example.data.models.Word item = db.wordDao().getTheIndexOfTopWord();
              Word word = new Word(item.getWordId(), item.getWord(), item.getWordLength());
              return word;
          }
      });
  }
  }
  </code></pre>
  
  <p>GetAllWordsUseCase in Domain Layer:</p>
  
  <pre><code>public class GetAllWords extends UseCase&lt;List&lt;Word&gt;, GetAllWords.Params&gt; {
  
  private WordRepository wordRepository;
  
  public GetAllWords(PostExecutionThread postExecutionThread, WordRepository wordRepository) {
      super(postExecutionThread);
      this.wordRepository = wordRepository;
  }
  
  @Override
  public Observable&lt;List&lt;Word&gt;&gt; buildUseCaseObservable(Params params) {
      return wordRepository.getAllWords();
  }
  
  public static final class Params {
      private Params() {
      }
  
      public static GetAllWords.Params getAllWords() {
          return new GetAllWords.Params();
      }
  }
  }
  </code></pre>
  
  <p>UseCase Base Class in domain layer:</p>
  
  <pre><code>public abstract class UseCase&lt;T, Params&gt; {
  
  private final PostExecutionThread postExecutionThread;
  private final CompositeDisposable compositeDisposable;
  
  public UseCase(PostExecutionThread postExecutionThread) {
      this.postExecutionThread = postExecutionThread;
      this.compositeDisposable = new CompositeDisposable();
  }
  
  /**
   * Builds an {@link Observable} which will be used when executing the current {@link UseCase}.
   */
  public abstract Observable&lt;T&gt; buildUseCaseObservable(Params params);
  
  /**
   * Dispose from current {@link CompositeDisposable}.
   */
  public void dispose() {
      if (!compositeDisposable.isDisposed()) {
          compositeDisposable.dispose();
      }
  }
  
  /**
   * Executes the current use case.
   *
   * @param observer {@link DisposableObserver} which will be listening to the observable build
   *                 by {@link #buildUseCaseObservable(Params)} ()} method.
   * @param params   Parameters (Optional) used to build/execute this use case.
   */
  public void execute(DisposableObserver&lt;T&gt; observer, Params params) {
      if (observer != null) {
          final Observable&lt;T&gt; observable = this.buildUseCaseObservable(params)
                  .subscribeOn(Schedulers.io())
                  .observeOn(postExecutionThread.getScheduler());
          addDisposable(observable.subscribeWith(observer));
      }
  }
  
  /**
   * Dispose from current {@link CompositeDisposable}.
   */
  private void addDisposable(Disposable disposable) {
      if (disposable != null &amp;&amp; compositeDisposable != null)
          compositeDisposable.add(disposable);
  }
  }
  </code></pre>
  
  <p>Finally, WordActivity in Presentation Layer</p>
  
  <pre><code>public class WordActivity extends BaseActivity&lt;WordViewModel&gt; implements 
  View.OnClickListener, WordNavigator {
  
  @Inject
  WordViewModel wordViewModel;
  
  private Button deleteButton, updateButton, addButton;
  private EditText editTextWord;
  private WordListAdapter adapter;
  
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_word);
      ((MainApplication) getApplicationContext()).getComponent().inject(this);
      editTextWord = findViewById(R.id.activity_word_et_word);
      deleteButton = findViewById(R.id.activity_main_delete_button);
      updateButton = findViewById(R.id.activity_main_update_button);
      addButton = findViewById(R.id.activity_word_btn_add_word);
  
      deleteButton.setOnClickListener(this);
      updateButton.setOnClickListener(this);
      addButton.setOnClickListener(this);
  
  
      RecyclerView recyclerView = findViewById(R.id.recyclerview);
      adapter = new WordListAdapter(this);
      recyclerView.setAdapter(adapter);
      recyclerView.setLayoutManager(new LinearLayoutManager(this));
  
      getViewModel().setNavigator(this);
  
      getViewModel().getAllWords();
  
      getViewModel().getWords().observe(this, new Observer&lt;List&lt;Word&gt;&gt;() {
          @Override
          public void onChanged(@android.support.annotation.Nullable List&lt;Word&gt; words) {
              adapter.setWords(words);
          }
      });
  
  }
  
  @Override
  public void onClick(View v) {
      switch (v.getId()) {
          case R.id.activity_main_delete_button:
              getViewModel().getTheIndexOfTopWord(TOP_INDEX_ACTION_DELETE);
              break;
          case R.id.activity_main_update_button:
              getViewModel().getTheIndexOfTopWord(TOP_INDEX_ACTION_UPDATE);
              break;
          case R.id.activity_word_btn_add_word:
              handleAddButtonClick();
              break;
      }
  }
  
  public void handleAddButtonClick() {
      String text = editTextWord.getText().toString();
      if (text.equals("")) {
          Toast.makeText(getApplicationContext(), R.string.empty_not_saved, Toast.LENGTH_LONG).show();
      } else {
          Word word = new Word(text, text.length());
          getViewModel().insertWord(word);
          editTextWord.setText("");
          editTextWord.clearFocus();
      }
  }
  
  @Override
  public void updateTopIndex(Integer wordId, String action) {
      if (action.equals(TOP_INDEX_ACTION_DELETE))
          getViewModel().deleteThisWord(wordId);
      else
          getViewModel().updateThisWord(wordId, "dsakagdad");
  }
  
  @Override
  public WordViewModel getViewModel() {
      return wordViewModel;
  }
  }
  
  
  **getViewModel().getWords().observe(this, new Observer&lt;List&lt;Word&gt;&gt;() {
      @Override
      public void onChanged(@android.support.annotation.Nullable List&lt;Word&gt; words) {
          adapter.setWords(words);
      }
  });**
  
  //This portion is getting called only once but not when I 
    insert/update/delete words from room database!
  </code></pre>
  
  <p>Can anyone go through these and help me out here!</p>