Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize LiveData In AndroidViewModel

I am looking for a way to initialize the LiveData object inside the ViewModel. Items are currently only getting initialized when setQuery method is called from the activity.

public class MyListViewModel extends AndroidViewModel {

private final LiveData <List<Item>> items;
private final MutableLiveData<String> query = new MutableLiveData<>();


private MyDatabase db;

public MyListViewModel(Application application) {
    super(application);
    db  = MyDatabase.getInstance(application);
    items = Transformations.switchMap(query, (search)->{
        if (search == null || search.trim().length() == 0) {
            return db.itemDao().getAllItems();
        } else {
            return db.itemDao().findItemsBySearchTerm(search);
        }
    });

}

public LiveData<List<Item>> getItems() {
    return items;
}

public void setQuery(String queryText) {
   query.setValue(queryText);
}

}

like image 664
Ved Agarwal Avatar asked Dec 31 '17 16:12

Ved Agarwal


People also ask

How do I declare LiveData?

Follow these steps to work with LiveData objects: Create an instance of LiveData to hold a certain type of data. This is usually done within your ViewModel class. Create an Observer object that defines the onChanged() method, which controls what happens when the LiveData object's held data changes.

Why should you initialize and store LiveData in your ViewModel instead of a UI controller?

Why should you initialize and store LiveData in your ViewModel instead of a UI Controller? Both the ViewModel and LiveData are lifecycle aware. To ensure that the LiveData isn't destroyed when the UI Controller is destroyed. To hide or separate implementation details making your app more flexible.

Can I use LiveData without ViewModel?

To answer your question, No, It is not mandatory to use LiveData always inside ViewModel, it is just an observable pattern to inform the caller about updates in data. If you have something which won't be changed frequently and can be accessed by its instance.


1 Answers

You have to call setQuery(String queryText) at least once As per Transformation documentation

The transformations aren't calculated unless an observer is observing the returned LiveData object. Because the transformations are calculated lazily, lifecycle-related behavior is implicitly passed down without requiring additional explicit calls or dependencies.

So that if you don't call setQuery(String queryText) from Activity it will not update MutableLiveData<String> query and will not trigger the Transformation.

If you want to avoid initial call from Activity you can call it below the Transformation initialization like this,

public MyListViewModel(Application application) {
    super(application);
    db  = MyDatabase.getInstance(application);
    items = Transformations.switchMap(query, (search)->{
        if (search == null || search.trim().length() == 0) {
            return db.itemDao().getAllItems();
        } else {
            return db.itemDao().findItemsBySearchTerm(search);
        }
    });
    setQuery("")
}

It will trigger the empty search part and will return All Items.

Also you need to observe the returned data in your case items. If no observer is observing the data then Transaction will not trigger.

As I referred from Documentation and few Blogs this worked for me

like image 65
adityakamble49 Avatar answered Sep 19 '22 04:09

adityakamble49