Search code examples
androidandroid-architecture-componentsandroid-livedataandroid-viewmodel

Android MVVM: How to handle network request failiures?


I am new to Android Arch components. I am trying to make a basic todo app using Android View Model and Live Data. What is the best way to make network calls when following MVVM pattern? I need to show a progress bar when a network request starts and dismiss it when the call is complete and in case of errors I need to display a snackbar with the relevant error message. Is it possible to do this without using an AsyncTask?

Remote Repository Class:

public class RemoteRepository {
private APIService apiService;

public RemoteRepository (APIService apiService) {
    this.apiService= apiService;
}

public LiveData<List<Project>> getList(String userId) {
    final MutableLiveData<List<Project>> data = new MutableLiveData<>();

    apiService.getList(userId).enqueue(new Callback<List<Project>>() {
        @Override
        public void onResponse(Call<List<Project>> call, Response<List<Project>> response) {
            data.setValue(response.body());
        }

        @Override
        public void onFailure(Call<List<Project>> call, Throwable t) {
            // What to do to show snackbar in activity
        }
    });
    return data;
}

Do we need to use an async task and manage the UI in its preExecute and postExecute callbacks? Or is it possible to do it with Observable Livedata objects?


Solution

  • You can do it this way.

    Create a class that has a Throwable and desire success result object. create a constructor or getter setter method to set values. ProjectRepoClass is an example of it.

    Project Repo Class::

    public class ProjectRepoModel {
    
    private List<Project> mList;
    private Throwable mThrowable;
    
    public ProjectRepoModel (List<Project> mList) {
        mList= mList;
    }
    
    public ProjectRepoModel (Throwable throwable) {
        mThrowable = throwable;
    }
    
    public List<Project> getList() {
        return mList;
    }
    
    public Throwable getThrowable() {
        return mThrowable;
    }
    
    }
    

    Set value according to API result. it can be an error or success response and return it.

    Return data:

    public LiveData<List<Project>> getList(String userId) {
    final MutableLiveData<ProjectRepoModel > data = new MutableLiveData<>();
    
    apiService.getList(userId).enqueue(new Callback<List<Project>>() {
        @Override 
        public void onResponse(Call<List<Project>> call, Response<List<Project>> response) { 
            data .setValue( new ProjectRepoModel (response.body()));
        } 
    
        @Override 
        public void onFailure(Call<List<Project>> call, Throwable t) { 
            data .setValue( new ProjectRepoModel (t));
        } 
    }); 
    return data;
    } 
    

    Create Observable for live data in the UI part and make a check for error and display results according to it.

    Observe result In UI Like this:

    if (mModel.getThrowable() != null)
      {
            // Show error
      } else {
    
           // display success result
    
      }
    

    This how you can achieve the error handle from the repository in MVVM.