Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instance member LiveData variable in ViewModel?

I am trying to understand Android Architecture Components after a couple of years break on Android. One thing that confuses me after reading the official documentation and a few blogs is where to create LiveData variables.

In the first variant below I created a livedata variable only in the repository class and in the second variant in both repository and View model class. Both variants works.

First variant:

public class ScoreViewModel extends AndroidViewModel {

    private ScoreRepositorDB scoreRepo;

    public ScoreViewModel(Application application) {
        super(application);
        scoreRepo = new ScoreRepositorDB(application);
    }

    public LiveData<Score> getScore(){
        return scoreRepo.getScore();   
    }
    ...
 }

Second variant:

public class ScoreViewModel extends AndroidViewModel {

    private ScoreRepositorDB scoreRepo;
    private LiveData<Score> score ;

    public ScoreViewModel(Application application) {
        super(application);
        scoreRepo = new ScoreRepositorDB(application);
        score =  scoreRepo.getScore();
    }

    public LiveData<Score> getScore(){
       // return scoreRepo.getScore();
       return score;

    }
    ...
  }

The repository for both variants :

private LiveData<Score> score ;

ScoreRepositorDB(Application application) {
    ScoreRoomDatabase db = ScoreRoomDatabase.getDatabase(application);
    scoreDao = db.scoreDao();
    score = scoreDao.getScore(1);
}

public LiveData<Score> getScore(){
    return score;
}
...

In this example, should I create :

 private LiveData<Score> score ;

in the ViewModel? And more generally , where should I put instance LiveData/MutableLiveData variable and why?

like image 730
u2gilles Avatar asked Nov 08 '22 05:11

u2gilles


1 Answers

I'll answer your general question first:

And more generally , where should I put instance LiveData/MutableLiveData variable and why?

The short answer is it depends. Usually, if you're working with LiveData only you'd pass the LiveData that comes from you repository straight to the ViewModel and the ViewModel would simply expose it to the View, with no need of creating an instance of it in the ViewModel.

But, if for any reason you'd need to modify the LiveData in the ViewModel you should hold a reference to it in the ViewModel, you can clearly see it in this google sample:

 public LiveData<ProductEntity> loadProduct(final int productId) {
        return mDatabase.productDao().loadProduct(productId);
    }

The repository simply gets the LiveData provided by the Room Library and exposes it. The View model, gets the LiveData and exposes it to the View:

public ProductViewModel(@NonNull Application application, DataRepository repository,
            final int productId) {
        super(application);
        mProductId = productId;
        mObservableProduct = repository.loadProduct(mProductId);
    }

public LiveData<ProductEntity> getObservableProduct() {
    return mObservableProduct;
}

You can hold to a reference of the result LiveData as seen above. But you could have passed it straight to the view:

public LiveData<ProductEntity> getObservableProduct() {
    return repository.loadProduct(mProductId);
}

What I've been seeing lately is if you're working with Retrofit and a remote repository (or even with Room) you can work with RxJava (or Retrofit's native callbacks) and that way you'd need an instance of LiveData in your ViewModel.

So the difference is that if you're working only with LiveData (from the data source to the view) you could hold a reference to your live data in the ViewModel. If your working half way through only you must have a LiveData in the view model.

Finally in you case you can hold the reference just like in the google sample.

like image 138
Levi Moreira Avatar answered Nov 17 '22 07:11

Levi Moreira