im trying to do login using retrofit and viewmodel
i have done successfully login with only retrofit...referred this tutorial--> https://www.youtube.com/watch?v=j0
ViewModel is nothing but a mediator. It just hold data with it's own lifecycle.
If you are trying to follow MVVM, you have to clean your code first.
Make data source, viewmodel and view seperate. All of them has seperate task to do. For better understanding about MVVM please follow this link
Following code may help you:
Create a LoginDataSource
class LoginDataSource(private val context: Context) {
interface LoginCallBack {
fun onSuccess();
fun onError(message: String?)
}
fun login(email: String, password: String, loginCallBack: LoginCallBack) {
RetrofitClient.instance.userLogin(email, password)
.enqueue(object : Callback {
override fun onFailure(call: Call, t: Throwable) {
loginCallBack.onError(t.localizedMessage)
}
override fun onResponse(
call: Call,
response: Response
) {
var res = response
if (res.body()?.status==200) {
SharedPrefManager.getInstance(context)
.saveUser(response.body()?.data!!)
loginCallBack.onSuccess()
} else {
try {
val jObjError = JSONObject(response.errorBody()!!.string())
loginCallBack.onError(jObjError.getString("user_msg"))
} catch (e: Exception) {
loginCallBack.onError(e.message)
}
}
}
})
}
}
Then create a ViewModelFactory
class LoginViewModelFactory(val loginDataSource: LoginDataSource) : ViewModelProvider.Factory {
override fun create(modelClass: Class): T {
return modelClass.getConstructor(LoginDataSource::class.java)
.newInstance(loginDataSource)
}
}
ViewModel class:
class LoginViewModel(private val loginDataSource: LoginDataSource) : ViewModel() {
val loginSuccess = MutableLiveData()
val loginFailedMessage = MutableLiveData()
fun login(email: String, password: String) {
loginDataSource.login(email, password, object: LoginDataSource.LoginCallBack {
override fun onSuccess() {
loginSuccess.postValue(true)
}
override fun onError(message: String?) {
loginSuccess.postValue(false)
loginFailedMessage.postValue(message)
}
})
}
}
Finally Activity class:
class LoginActivity : BaseClassActivity() {
private lateinit var viewModel: LoginViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.login_activity)
val dataSource = LoginDataSource(applicationContext)
viewModel = ViewModelProvider(this, LoginViewModelFactory(dataSource)).get(LoginViewModel::class.java)
val button = findViewById(R.id.plusbutton)
val forgotpassword = findViewById(R.id.forgotpassword)
viewModel.loginSuccess.observe(this, Observer {
if(it) {
val intent = Intent(applicationContext, HomeActivity::class.java)
intent.flags =
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
finish()
}
})
viewModel.loginFailedMessage.observe(this, Observer {
showToast(applicationContext, it)
})
button.setOnClickListener {
val i = Intent(applicationContext, RegisterActivity::class.java)
startActivity(i)
}
forgotpassword.setOnClickListener {
val i = Intent(applicationContext, ForgotPassword::class.java)
startActivity(i)
}
loginbtn.setOnClickListener {
val email = loginuser.text.toString().trim()
val password = loginpassword.text.toString().trim()
if (email.isEmpty()) {
Toast.makeText(
applicationContext, "Data is missing", Toast.LENGTH_LONG
).show()
loginuser.error = "Email required"
loginuser.requestFocus()
return@setOnClickListener
} else if (password.isEmpty()) {
loginpassword.error = "Password required"
loginpassword.requestFocus()
return@setOnClickListener
} else {
viewModel.login(email, password)
}
}
}
}