title: Using ViewModel to only invoke on user intervention
body: <p>On my fragment where a user is checked to see whether their email is in the database and either go to the sign up or login flow, I use a ViewModel, this viewmodel uses email as MutableLiveData, this works fine, however when a user goes back, it will remember that email is already saved and then talk to the API instantly, pushing them back forward again.</p>
  
  <p>What method is used for waiting for a user to invoke? With everything else so far, with menus, it was right that it would fetch the data without user intervention and change the data on display to the user if changed. This however is different.</p>
  
  <p>My (admittedly poor) viewmodel is:</p>
  
  <pre><code>public class ExistingUserViewModel extends ViewModel {
      private final MutableLiveData&lt;String&gt; email = new MutableLiveData&lt;&gt;();
      private final LiveData&lt;ApiResponse&lt;ExistingUserResponse&gt;&gt; existingUser;
  
      @Inject
      public ExistingUserViewModel(@NonNull ExistingUserRepository existingUserRepository){
          existingUser = Transformations.switchMap(email, input -&gt; {
              if (input == null){
                  return AbsentLiveData.create();
              }
              return existingUserRepository.isExistingUser(input);
          });
      }
  
      public LiveData&lt;ApiResponse&lt;ExistingUserResponse&gt;&gt; getIsExistingUser() { return existingUser; }
  
      @VisibleForTesting
      public void setEmail(String email1){
          email.setValue(email1);
      }
  }
  </code></pre>
  
  <p>My Fragment:</p>
  
  <pre><code>@Override
  public void onActivityCreated(@Nullable Bundle savedInstanceState) {
      super.onActivityCreated(savedInstanceState);
      ((MainActivity) getActivity()).getSupportActionBar().hide();
      existingUserViewModel = ViewModelProviders.of(this, viewModelFactory).get(ExistingUserViewModel.class);
      existingUserListener();
  }
  
  private void refreshAndObserve() {
      existingUserViewModel.getIsExistingUser().observe(this, result -&gt; {
          if (result.isSuccessful()) {
              try {
                  String email = binding.get().emailEditText.getText().toString();
                  if (result.body.getExists()) { // user exists
                      navigationController.navigateToLogin(email,null);
                  } else {
                      navigationController.navigateToRegisterName(email);
                  }
              } catch (NullPointerException e){
                  Toast.makeText(getActivity(),e.toString(),Toast.LENGTH_SHORT).show();
              }
          } else {
              Toast.makeText(getActivity(),result.errorMessage,Toast.LENGTH_SHORT).show();
          }
      });
  }
  
  private void existingUserListener(){
      binding.get().continueButton.setOnClickListener(v -&gt; submitDetails(v));
      binding.get().emailEditText.setOnKeyListener((v, keyCode, event) -&gt; {
          if ((event.getAction() == KeyEvent.ACTION_DOWN)
                  &amp;&amp; (keyCode == KeyEvent.KEYCODE_ENTER)) {
              submitDetails(v);
              return true;
          }
          return false;
      });
  }
  
  private void submitDetails(View v) {
      refreshAndObserve();
      String email = binding.get().emailEditText.getText().toString();
      dismissKeyboard(v.getWindowToken());
      //todo: if valid do below
      existingUserViewModel.setEmail(email);
  }
  </code></pre>
  
  <p>I have played around when to do the observe but not sure how is best to deal with this data retention issue</p>