Miyel
Miyel

Reputation: 3

Android - How to supply an argument to a method in my ViewModel from my fragment

I'm fairly new to android kotlin, so in my ViewModel I have a method that accepts an integer as an argument. Currently the app is working because I am passing the integer argument from a global variable, now I want to be able to either call the ViewModel method in my fragment or call it in an init block in the ViewModel.

Here's my current View Model code:

class PostCommentViewModel: ViewModel() {

    private val TAG = "MainActivity"
    val mPostsComment = MutableLiveData<List<Comment>>()
    var postId: Int = 0


    init {
        postId = temp
        Log.e("Init on PostCommentViewModel", "Message: $postId")
        getDataComment(postId)

    }

     fun getDataComment(postId: Int) {
        PostRepository().getDataComment(postId).enqueue(object : Callback<List<Comment>>{
            override fun onResponse(call: Call<List<Comment>>, response: Response<List<Comment>>) {
                val comments = response.body()
                comments?.let {
                    mPostsComment.value = comments!!
                }
            }

            override fun onFailure(call: Call<List<Comment>>, t: Throwable) {
                Log.e(TAG, "On Failure: ${t.message}")
                t.printStackTrace()
            }
        })
    }

    fun getComments():MutableLiveData<List<Comment>>{
        return mPostsComment
    }


}

And here's my fragment where I get the value for the argument:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        checkArguments()
    }

    private fun checkArguments() {
        arguments?.let { bundle ->
            if (bundle.containsKey("POST")) {
                val postString = bundle.getString("POST", "")
                val post: Post = gson.fromJson(postString, Post::class.java)

                binding.postDetailstvTitle.text = post.title
                binding.postDetailstvBody.text = post.body
                param2 = post.id


                //val model: PostCommentViewModel by viewModels()
                //model.getDataComment(param2)
                temp = param2
            }
        }
    }

temp is the global variable. You can also see my attempt there to call the method haha. Big thanks to whoever answers <3

Upvotes: 0

Views: 688

Answers (1)

Pratik
Pratik

Reputation: 30855

You can use another MutableLiveData and observe it in Fragment.

In your ViewModal class

val postIdData= MutableLiveData<Int>(0) // here default set as 0

Now in your Fragment use this as observable as below in viewCreated(). Assuming you know how to initialized viewModel in your Fragment class.

viewModel.postIdData.observe(requiredActivity, { postId->{
  // now here you will get postId whenever data change
})

your code to get postId just post your value whenever you get it

private fun checkArguments() {
    arguments?.let { bundle ->
        if (bundle.containsKey("POST")) {
            val postString = bundle.getString("POST", "")
            val post: Post = gson.fromJson(postString, Post::class.java)

            binding.postDetailstvTitle.text = post.title
            binding.postDetailstvBody.text = post.body
            param2 = post.id


            //val model: PostCommentViewModel by viewModels()
            //model.getDataComment(param2)
            temp = param2
            // here postvalue 
            viewModel.postIdData.postValue(post.id)
        }
    }
}

Upvotes: 1

Related Questions