How to refresh data in Architecture Components ViewModel
Asked Answered
C

2

8

I'm having the following ViewModel:

public class FeedViewModel extends ViewModel {

private final FeedRepository repository;
private LiveData<Resource<List<Photo>>> feed;

@Inject
FeedViewModel(@NonNull final FeedRepository repository) {
    this.repository = repository;
}

LiveData<Resource<List<Photo>>> getUserFeed() {
    if (feed == null) {
        feed = new MutableLiveData<>();
        feed = repository.get();
    }
    return feed;
}

}

I observe feed in the Fragment this way:

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    viewModel.getUserFeed().observe(this, feed -> {
        switch (feed.status) {
            case ERROR:
                processErrorState(feed.data);
                break;
            case LOADING:
                processLoadingState(feed.data);
                break;
            case SUCCESS:
                if (feed.data != null)
                    processSuccessState(feed.data);
                break;
        }
    });
}

The question is: how can I refresh feed the right way? Let's suppose that user triggered swipeToRefresh, so that event must create a refresh task of feed. How can I implement this?

Caprine answered 9/4, 2018 at 15:41 Comment(1)
May you provide the answer in case you got one?Personalize
A
2

You will have to fetch the data and update live data using liveData.post(new data)

In your Activity: 
//to be called on refresh data 
viewModel.getLatestFeed()

In your View Model:
fun getLatestFeed() {
//get data from repository
feed.post(refreshedData)
}
Auxochrome answered 9/4, 2018 at 15:59 Comment(0)
C
2

You can use a "loadTrigger" to trigger data load , when swiping to refresh .

Add this code to your fragment :

 viewModel.userFeeds.observe( 
     //add observation code
  )
 swipToRefresh.setOnRefreshListener {
        viewModel.loadFeeds()
 }

and in the viewModel :

 val loadTrigger = MutableLiveData(Unit)

 val userFeeds = loadTrigger.switchMap { 
     repository.get()
 }
 fun loadFeeds() {
    loadTrigger.value = Unit
    //livedata gets fired even though the value is not changed
}

The solution is suggested here : manual refresh without modifying your existing LiveData

I tested it and it workes well.

Compurgation answered 2/2, 2021 at 9:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.