Reputation: 2519
I am trying to use MutableLiveData
with pre-filled value from database, but Observer
always returns null
as book
. I need to keep it as MutableLiveData
, NOT LiveData
, because I have to set it programatically on some places. Therefore I am calling setValue
with LiveData
retrieved from DB. Code:
ViewModel
:
private final MutableLiveData<Book> bookLiveData;
public MyViewModel(@NonNull Application application) {
super(application);
...
book = new MutableLiveData<>();
bookLiveData.setValue(bookRep.getBookLiveData().getValue());
....
}
Fragment
:
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
...
getActivity().getBookLiveData().observe(getViewLifecycleOwner(), book -> {
... // When fragment is created, book is always null here
});
}
Can somebody tell me why is Book
null in observer? I thought that Observer
would be notified when bookRep.getBookLiveData()
is finished and value is retrieved. THank you for your help.
Upvotes: 1
Views: 2946
Reputation: 3494
bookRep.getBookLiveData().getValue()
will always return null
. Since you are setting a null
value in the ViewModel like this: bookLiveData.setValue(null)
at line 7, bookLiveData
is always null
at initial launch.
You cannot use getValue()
on a LiveData
object to get value here because it is always null at initialization. You need to observe so that you get notified when it actually emits a value.
There are several different ways to solve it. One way is to observe getBookLiveData()
in the ViewModel using observeForever()
method.
private LiveData<Book> bookFromRep;
private MutableLiveData<Book> bookLiveData = new MutableLiveData<>();
private Observer<Book> bookObserver = bookLiveData::postValue; // Book observer posts value to bookLiveData.
public MyViewModel(@NonNull Application application) {
super(application);
...
bookFromRep = bookRep.getBookLiveData();
bookFromRep.observeForever(bookObserver);
....
}
@Override
protected void onCleared() {
super.onCleared();
// Don't forget to remove observer when you use observeForever()
bookFromRep.removeObserver(bookObserver);
}
Another, and arguably a better, approach to this problem is to use MediatorLiveData. I won't include its implementation here but what I recommend is to understand different approaches and find the best approach that fits your need.
Upvotes: 2