Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - MVVM with LiveData component and a Retrofit call in Repository

I would like to use the following components for an authentication view (Login):

  • MVVM
  • LiveData
  • Retrofit
  • Repository

I don't know how can i recieve asynchronous Retrofit call in Repository class to current ViewModel.

View -> ViewModel -> Repository with LiveData.

Someone would have an idea or an example to archieve this ?

like image 977
rmarbaix Avatar asked Oct 18 '18 13:10

rmarbaix


2 Answers

You can do like below :

YourActivity.kt

class YourActivity : AppCompatActivity() {

private val myViewModel by lazy {
    return@lazy ViewModelProviders.of(this).get(MyViewModel::class.java) }
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onViewReady(savedInstanceState)
    myViewModel.callApi() // You can do it anywhere, on button click etc..
    observeResponseData() // observe it once in onCreate(), it'll respect your activity lifecycle
}

private fun observeResponseData() {
    myViewModel.liveData.observe(this, Observer { data ->
        // here will be your response
    })
}
}

MyViewModel.kt

class MyViewModel : ViewModel() {

val liveData = MutableLiveData<Your response type here>()
val myRepository = MyRepository()

fun callApi() {
    myRepository.callMyRetrofitApi(liveData)
}
}

MyRepository.kt

class MyRepository {
//Make your retrofit setup here

//This is the method that calls API using Retrofit
fun callMyRetrofitApi(liveData: MutableLiveData<Your response type here>) {
    // Your Api Call with response callback
    myRetrofitInstance.apiMethod.enqueue(object : Callback<Your response type here> {
        override fun onFailure(call: Call<Your response type here>, t: Throwable) {

        }

        override fun onResponse(call: Call<Your response type here>, response: Response<Your response type here>) {
            liveData.value = response.body()
        }

    })
}
}

Try to do setup like this.

Hope it helps !

like image 182
Jeel Vankhede Avatar answered Oct 16 '22 15:10

Jeel Vankhede


The easiest way to design your project in MVVM using LiveData and Retrofit is to use LiveData in your ViewModel class and Retrofit in your Repository.

In layman terms, you get data from your Repository in your ViewModel class and in your ViewModel class, you pass this data to the MutableLiveData and then this MutableLiveData can be observed in your view by converting it into LiveData.

MainActivity.java

public class MainActivity extends AppCompatActivity {
        private MainViewModel mainViewModel;

      @Override
      protected void onCreate(@Nullable Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_instruction);
                mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
                mainViewModel.init();
                mainViewModel.getModelLiveData().observe(this, new Observer<MainResponse>() {
                @Override
                public void onChanged(@Nullable MainResponse mainResponse) {
                // Here you write logic which implements if the ViewModel data changes. 
             }}
         });
      }
    }

MainViewModel (your ViewModel)

public class MainViewModel extends ViewModel {
private MainRepo mainRepo;
private MutableLiveData<MainResponse> modelMutableLiveData = new MutableLiveData<>();
Disposable disposable;

public MainViewModel() {
}

public MainViewModel(MainRepo mainRepo) {
    this.mainRepo = mainRepo;
}

public void init() {
                    modelMutableLiveData.setValue(mainRepo.callRetrofit().body());
                }

public LiveData<MainResponse> getModelLiveData() {
    return modelMutableLiveData;
   }
}

MainRepository (your repository class)

    public class MainRepository{

            public void callRetrofit() {
                    apiInterface = 
        ApiClient.getClient(ApiClient.POST_STATUS_URL).create(ApiInterface.class);
        Call<ModelForPostRequest> call = apiInterface.likeItem(modelForPostRequest);
        call.enqueue(new Callback<ModelForPostRequest>() {
        @Override
        public void onResponse(Call<ModelForPostRequest> call, 
                Response<ModelForPostRequest> response) {
            //do something here
        }

        @Override
        public void onFailure(Call<ModelForPostRequest> call, Throwable t) {
        }
    });
}}
like image 1
Abhishek Kumar Avatar answered Oct 16 '22 15:10

Abhishek Kumar