Search code examples
kotlinviewmodelandroid-livedata

How to use ViewModel in Kotlin


I need to save the data downloaded from the server when the screen is rotated. I'm trying to do this using the ViewModel. But I get typeMismach here model.getJokes().observe(this, object : Observer<List<Jokes>>()

class ItemsFragment : Fragment() {

var type: String? = ""
private var api: Api? = null
var adapter = ItemsAdapter()
private var jokes: List<Jokes> = ArrayList()
private var jokesCount: Int? = null
private var items: Result? = null
private var itemsCount: ResultCount? = null


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val args = arguments
    type = args?.getString(KEY_TYPE)

    api = (activity?.application as App).api

    val model = ViewModelProviders.of(this).get(JokesViewModel::class.java)
    model.getJokes().observe(this, object : Observer<List<Jokes>>() {
        fun onChanged(@Nullable jokesList: List<Jokes>) {
            adapter = ItemsAdapter()
            recycler.adapter = adapter
        }
    })
}

class JokesViewModel : ViewModel() {

private var api: Api? = null
var adapter = ItemsAdapter()
private var jokes: List<Jokes> = ArrayList()
private var items: Result? = null

private var jokeList: MutableLiveData<List<Jokes>>? = null

fun getJokes(): LiveData<List<Jokes>> {
    if (jokeList == null) {
        jokeList = MutableLiveData()
        loadItems(5)
    }

    return jokeList as MutableLiveData<List<Jokes>>
}


private fun loadItems(jokeCount: Int?) {
    val call = api?.getItems(jokeCount)

    call?.enqueue(object : Callback<Result> {
        override fun onResponse(call: Call<Result>, response: Response<Result>) {
            items = response.body()
            jokes = items!!.value
            items?.let { adapter.setJokes(jokes) }
            adapter.notifyDataSetChanged()
        }

        override fun onFailure(call: Call<Result>, t: Throwable) {
            println(t)
        }
    })
}

}


Solution

  • In Fragment this is not a lifecycle owner try using requireActivity() or viewLifecycleOwner refer this

    Edit #3 Problem was in importing Observer. This code works fine:

    try

    model.getJokes().observe(requireActivity(), android.arch.lifecycle.Observer{ it -> 
        fun onChanged(@Nullable jokesList: List<Jokes>) {
            // do something
        }
        onChanged(it)
    })
    
    

    Otherwise, you should make sure List not null by using List<Jokes!>!