https://kotlinlang.org logo
#compose
Title
# compose
a

Artur Matsehor

06/16/2020, 2:45 PM
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

andylamax

06/16/2020, 2:48 PM
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

Artur Matsehor

06/16/2020, 2:48 PM
And what if I don't want to use neither Rx or LiveData ?
a

andylamax

06/16/2020, 2:49 PM
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

henrikhorbovyi

06/16/2020, 2:51 PM
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

Artur Matsehor

06/16/2020, 2:53 PM
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

andylamax

06/16/2020, 3:03 PM
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

Artur Matsehor

06/17/2020, 9:31 PM
Thanks for your help! I did pretty much what you've gave (with some complications) and it worked)
a

andylamax

06/18/2020, 11:53 AM
welcome @Artur Matsehor
8 Views