I am going through Guide to app architecture and trying to implement MVVM and LiveData in one of my apps. I am using realm and I am using this to create a RealmLiveData as shown below

class RealmLiveData<T : RealmModel>(private val results: RealmResults<T>) : MutableLiveData<RealmResults<T>>() {
private val listener = RealmChangeListener<RealmResults<T>> { results -> value = results }
override fun onActive() {
    results.addChangeListener(listener)
}

override fun onInactive() {
    results.removeChangeListener(listener)
}
}

This how I am updating the list to recyclerview

var mList:ArrayList<Notes> = ArrayList()

lateinit var historyViewModel: HistoryViewModel

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val view = inflater.inflate(R.layout.fragment_history, container, false)
    mRCview = view.findViewById(R.id.list)
    historyViewModel = ViewModelProviders.of(activity!!).get(HistoryViewModel::class.java)

    // this is how I observe
    historyViewModel.getList().observe(this, Observer{
        (mRCview.adapter as MyHistoryRecyclerViewAdapter).setData(it)
    })

    with(mRCview) {
        setHasFixedSize(true)
        layoutManager = LinearLayoutManager(mContext)
        mList = ArrayList()
        adapter = MyHistoryRecyclerViewAdapter(
            mContext as OnListFragmentInteractionListener
        )
    }
    return view
}

This is how I get the data in my repository class

class HistoryRepository {

fun getHistory(): RealmLiveData<Notes> {
    val realmInstance = Realm.getDefaultInstance()
    val realmResults = realmInstance
        .where(Notes::class.java)
        .findAll()
        .sort("lastUpdatedTimeStamp", Sort.DESCENDING)
    return realmResults.asLiveData()
}

fun <T:RealmModel> RealmResults<T>.asLiveData() = RealmLiveData(this)
}

EDIT

Here is the ViewModel

class HistoryViewModel: ViewModel() {

val repository = HistoryRepository()

fun getList(): RealmLiveData<Notes> {
    return repository.getHistory()
}
}

The issue is that the observer is not getting triggered for the first time. If I update the realmresult, the live data update gets invoked and updates my list. Please let me know how I can fix the issue.

Answer
    • You are adding results.addChangeListener(listener) in onAdded(). Since the listener is added after the first observer is attached to the LiveData, the existing data on realm will not be triggered. This is my guess, haven't used Realm.
    • @ArkaPravaBasu I called listener.onChange(results) after adding the changelistener. If you can add it as an answer I will accept it thanks Btw.. and sorry for my ignorance

We need to notify the Observer of the existing data. When the first Observer registers to historyViewModel.getList() you are registering the realm callback. At this point we need to trigger a change just to notify this Observer of the existing data.

Something like

class RealmLiveData<T : RealmModel>(private val results: RealmResults<T>) : MutableLiveData<RealmResults<T>>() {
private val listener = RealmChangeListener<RealmResults<T>> { results -> value = results }
override fun onActive() {
    results.addChangeListener(listener)
    listener.onChange(results) // notify the added Observer of the existing data.
}

override fun onInactive() {
    results.removeChangeListener(listener)
}
}
  • 1
Reply Report

Warm tip !!!

This article is reproduced from Stack Exchange / Stack Overflow, please click

Trending Tags

Related Questions