Arfin Hosain
Arfin Hosain

Reputation: 225

call a method from another class inside composable function

Iam new to jetpack compose, and trying to figure it out how it works. i am having problem, that i want to call a method inside my @Composable function which is in another class.

This is my main activity code

package com.example.bohubrihiwithjetpack

import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import com.example.bohubrihiwithjetpack.retrofit.RetrofitClient
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Response
import java.lang.Exception
import javax.security.auth.callback.Callback

class MainActivity : ComponentActivity() {
    private val weatherAPI = "rNCnpnQge4Il62hiTcLVX6FAr8IPG7oW"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            composable()

        }
    }

    fun getRegionsHttp() {
        RetrofitClient.getInstance().getApi()
            ?.getRegions(weatherAPI)
            ?.enqueue(object : retrofit2.Callback<ResponseBody> {
                override fun onResponse(
                    call: Call<ResponseBody>,
                    response: Response<ResponseBody>
                ) {
                    if (response.isSuccessful) {
                        val successFul = response.body()?.string()
                        Toast.makeText(this@MainActivity, successFul, Toast.LENGTH_SHORT).show()

                    } else {
                        try {
                            val errorDetect = response.errorBody()?.string()
                            val error = errorDetect
                            Toast.makeText(this@MainActivity, error, Toast.LENGTH_SHORT).show()

                        } catch (e: Exception) {
                            Toast.makeText(this@MainActivity, "something wrong", Toast.LENGTH_SHORT)
                                .show()

                        }
                    }
                }

                override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                    Toast.makeText(this@MainActivity, t.message, Toast.LENGTH_SHORT).show()
                }
            })
    }


}

Now i want to call the getRegionsHttp method inside the below @Composable function.

package com.example.bohubrihiwithjetpack

import androidx.compose.runtime.Composable

@Composable
fun composable() {
    
}

How do i do that?

Upvotes: 3

Views: 9214

Answers (2)

Islam Mansour
Islam Mansour

Reputation: 390

Just in case you decided to call api from composable function like that, I would like to highlight that this Api is going to be called an unexpected number of times because of the recomposition; therefore, you need to actually determine why would you do that. Calling an Api should be event based or maybe at the page loading time. As an example to load the API at the start you might find it here

Also Composables should be depending on states and actions to be passed from outside, and to avoid doing logic inside it as it is a declarative UI which should only describe the UI; however, to answer your question you might check the below code.

class MainActivity : ComponentActivity() {
private val weatherAPI = "rNCnpnQge4Il62hiTcLVX6FAr8IPG7oW"
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        composable { getRegionsHttp() }

    }
}



 @Composable
fun composable(regionsHttp:() ->Unit) {}

Upvotes: 2

dani
dani

Reputation: 149

Use viewModel

 class myViewModel: ViewModel() { 
    fun getRegionsHttp(resp: (Response<ResponseBody>) -> Unit) {
      viewModelScope.launch {
        RetrofitClient.getInstance().getApi()
            ?.getRegions(weatherAPI)
            ?.enqueue(object : retrofit2.Callback<ResponseBody> {
                override fun onResponse(
                    call: Call<ResponseBody>,
                    response: Response<ResponseBody>
                ) {
                   resp.invoke(response)
     
                }

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

In your composable function

@Composable
fun composable(viewModel: myViewModel) {
   val context = LocalContext.current
   viewModel.getRegionsHttp() {
       if (it.isSuccessful) {
          Toast.makeText(context, response.body()?.string(), Toast.LENGTH_SHORT)
       }
   }
}

if you using navigation you can pass your code like this

composable(viewModel())

Upvotes: 4

Related Questions