Spook
Spook

Reputation: 25929

Viewmodel observing LiveData - how?

Before Lifecycle and LiveData stuff, Viewmodel could observe changes to its own observables quite easily. It was only a matter of subscribing to Observable*'s changes and react to them. Then one might used a two-way binding to react immediately on user's input.

In Android Studio Canary, it is now allowed to bind to LiveData objects, provided that Binding knows lifecycle of its owner (ViewBinding now has additional setLifecycle method), by Android Studio Canary information:

You can now use a LiveData object as an observable field in data binding expressions. The ViewDataBinding class now includes a new setLifecycle method that you need to use to use to observe LiveData objects.

However, Viewmodel documentation states clearly:

ViewModel objects can contain LifecycleObservers, such as LiveData objects. However ViewModel objects must never observe changes to lifecycle-aware observables, such as LiveData objects.

(emphasis mine)

So how one can react immediately to LiveData changes if ViewModel cannot subscribe to them?

And, furthermore, why Viewmodel can not observe changes to its own LiveData?

Upvotes: 14

Views: 11212

Answers (2)

Saurabh Khare
Saurabh Khare

Reputation: 1277

I fixed this issue using MediatorLiveData. You can follow the steps below.

  1. Create a variable (ex. result).

    private final MediatorLiveData<Resource<RequestType>> result = new MediatorLiveData<>();
    
  2. Call addSource method where the first argument is LiveData and the second is an observer.

    LiveData<Resource<EmptyResponse>> observable = service.createItems();
    result.addSource(observable, response -> {
        //Write code here 
    }
    

Also see this SO answer. The basic requirement is almost the same.

Upvotes: 5

woodii
woodii

Reputation: 793

You can use Transformations to invoke actions if one of your LiveData Objects changes.

E.g. the user selects a person in a Spinner and you want to load the according person object.

MutableLiveData<Integer> personId = new MutableLiveData<>();
LiveData<Person> person = Transformations.switchMap(personId, id -> getPerson(id));

Upvotes: 3

Related Questions