임세준
임세준

Reputation: 154

livedata coroutine does not observe the data

I use MVVM architecture in my project. When it first called, it works. but after that, it does not work. here is my code.

 fun loadYgosuData() : LiveData<ArrayList<YgosuData>> {
   Log.d(TAG, "loadYgosuData()...")
   return liveData {
       Log.d(TAG, "liveData Scope running....")
       val element = withContext(Dispatchers.IO) {
           Jsoup.connect("https://www.ygosu.com/community/real_article")
               .get()
               .select("div.board_wrap tbody tr")
       }
       emit(setYgosuData(element))
   }

}

fun setYgosuData(tmpDoc: Elements?) : ArrayList<YgosuData> {
    var tmpList = ArrayList<YgosuData>()
    if (tmpDoc != null) {
        //Log.d(TAG, "element : $tmpDoc")
        for (e in tmpDoc) {
            var title = e.select("td.tit a")
            var name = e.select("td.name a")
            var read = e.select("td.read")
            var date = e.select("td.date")
            var url = e.select("td.tit a").attr("href").toString()
            var tmpYgosuData = YgosuData(
                title = title.text(),
                name = name.text(),
                read = read.text(),
                date = date.text(),
                url = url
            )
            tmpList.add(tmpYgosuData)

        }


    }
    Log.d(TAG, "여기2 ${tmpList.toString()}")
    return tmpList
}

Could you help me please? Thank you.

Upvotes: 1

Views: 610

Answers (1)

iamanbansal
iamanbansal

Reputation: 2732

From official doc

The liveData building block serves as a structured concurrency primitive between coroutines and LiveData. The code block starts executing when LiveData becomes active and is automatically canceled after a configurable timeout when the LiveData becomes inactive. If it is canceled before completion, it is restarted if the LiveData becomes active again. If it completed successfully in a previous run, it doesn't restart. Note that it is restarted only if canceled automatically. If the block is canceled for any other reason (e.g. throwing a CancelationException), it is not restarted.

That's why it works for the first time as you mentioned.

Solution1: combine liveData with Transformations

private val body: MutableLiveData<String> = MutableLiveData()

val YgousData = body.switchMap {
    liveData {
        Log.d(TAG, "liveData Scope running....")
        val element = withContext(Dispatchers.IO) {
            Jsoup.connect("https://www.ygosu.com/community/real_article")
                .get()
                .select("div.board_wrap tbody tr")
        }
        emit(setYgosuData(element))
    }
}

fun callApi(param:String){
    body.value = param
}

You can change the body based on which you want to trigger api call

Solution2: You can do api call explicitly and then post the data to livedata (w/o using livedata builder)

Upvotes: 2

Related Questions