Hi everyone I'm making a Compose-MVVM application ...
# compose
a
Hi everyone I'm making a Compose-MVVM application and trying to implement network requests and make UI react to responses. And now I'm struggling on how to do it properly So here's my pseudo-code
Copy code
@Composable
fun SampleScreen() {
    SampleScreenBody(viewModel = SampleViewModel())
}

@Composable
fun SampleScreenBody(viewModel: SampleViewModel) {
    Button(onClick = {
        viewModel.doSmth("Parameter") { response ->
            if (response == "Success") {
                //TODO: this is where I want to, for ex, move to another screen
                //or show a dialog.
                //How?
            }
        }
    }) {
        Text("Text")
    }
}
a
Speaking as a rookie in this, so bare with me on this one First: I don't think you should pass your viewmodel to a compose function. But do pass your exposed live data
☝️ 1
a
And what if I don't want to use neither Rx or LiveData ?
a
If it is MVVM you are doing, you must have an observable pattern in your viewmodel
then, the exposed observable should be passed down
h
If you don't want to use
LiveData
or
RX
use the delegate
observable
from kotlin or
StateFlow
from kotlinx.coroutines
But as @andylamax said: If you are doing MVVM you have to use the observable pattern
a
Well, even if I'll use LiveData/Rx/Flow/Channel, how it is got to change things ? Okay, I can use LiveData.observeAsState to get some State<T> object. But where and how should I declare the state variable ?
Copy code
@Composable
fun SampleScreenBody(viewModel: SampleViewModel) {
    Button(onClick = {
        val resultState = viewModel.doSmth("Parameter").observeAsState()
        
        // ???
    }) {
        Text("Text")
    }
}
a
Copy code
// If you are using viewModel
data class User(val name: String)

class VM : ViewModel {
  private val _user = MutableLiveData<User>
  val user : LiveData get() = _value

  fun updateUser(name: String) {
    _user.value = User(name)
  } 
}

class Activity : AppCompatActivity {
  private lateinit var vm:VM
  override fun onCreate(bundle: Bundle?) {
    vm = ViewModelProvidors.of(this)
    setContent {
      SampleScreen(vm.user.value) {vm.updateUser(it)}
    }
  }
}
@Composable
fun SampleScreen(user:User,onUserNameChanged:(String)->Unit) {
  // . . . User UI Implementation
  Button(onClick = {
       onUserNameChanged("New User")
    }) {
        Text(user.name)
    }
}
1
Sorry for the late response. I am relatively new to slack
Copy code
// Or Even this
data class User(val name: String)

class VM : ViewModel {
  private val _user = MutableLiveData<User>
  val user : LiveData get() = _value

  fun updateUser(name: String) {
    _user.value = User(name)
  } 
}

class Activity : AppCompatActivity {
  private lateinit var vm:VM
  override fun onCreate(bundle: Bundle?) {
    vm = ViewModelProvidors.of(this)
    setContent {
      SampleScreen(vm.user) {vm.updateUser(it)}
    }
  }
}
@Composable
fun SampleScreen(u:LiveData<User>,onUserNameChanged:(String)->Unit) {
  // . . . User UI Implementation
  val user = u.asObservableState()
  Button(onClick = {
       onUserNameChanged("New User")
    }) {
        Text(user.name)
    }
}
a
Thanks for your help! I did pretty much what you've gave (with some complications) and it worked)
a
welcome @Artur Matsehor