Home > OS >  If statement not working yet used correctly
If statement not working yet used correctly

Time:07-15

    class SignUp : AppCompatActivity() {
private lateinit var auth: FirebaseAuth
private var etEmail: String? = null
private var etPass: String? = null
private var etPass2: String? = null
private lateinit var btn: Button

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_sign_up)
    // Initialising
    auth= Firebase.auth
    etEmail = findViewById<EditText>(R.id.et_email).text.toString().trim()
    etPass = findViewById<EditText>(R.id.pass).text.toString()
    etPass2 = findViewById<EditText>(R.id.et_pass2).text.toString()
    btn = findViewById(R.id.btn_create)
    
    //Dialog
    val dialog = Dialog(this)
    dialog.setContentView(R.layout.custom_dialog)
    

    btn.setOnClickListener {
        dialog.show()

        if (isValid(etEmail, etPass, etPass2)){
            Toast.makeText(this,"Done", Toast.LENGTH_SHORT).show()
        }
        dialog.dismiss()
    }

}
private fun isValid(email: String?, pass: String?, pass2: String?): Boolean{
    return if (email.isNullOrEmpty() && pass.isNullOrEmpty()){
        Toast.makeText(this, "Fill in the blanks", Toast.LENGTH_SHORT).show()
        false
    }else if (pass != pass2){
        Toast.makeText(this, "Password do not match", Toast.LENGTH_SHORT).show()
        false
    }else{
        true
    }
}

I am trying to check if the user has entered his email and password. But when I test the app it brings up this toast ' Fill in the blanks ' in the private is valid function yet I have entered an email and password.

CodePudding user response:

Your error is in this part:

etEmail = findViewById<EditText>(R.id.et_email).text.toString().trim()
etPass = findViewById<EditText>(R.id.pass).text.toString()
etPass2 = findViewById<EditText>(R.id.et_pass2).text.toString()

You retrieve String values before any changes were made by user. You should get them only after user finished typing and clicked the button, so like this:

btn.setOnClickListener {
    dialog.show()

    val etEmail = findViewById<EditText>(R.id.et_email).text.toString().trim()
    val etPass = findViewById<EditText>(R.id.pass).text.toString()
    val etPass2 = findViewById<EditText>(R.id.et_pass2).text.toString()
    
    if (isValid(etEmail, etPass, etPass2)){
        Toast.makeText(this,"Done", Toast.LENGTH_SHORT).show()
    }
    dialog.dismiss()
}

This way you can remove this part completely:

private var etEmail: String? = null
private var etPass: String? = null
private var etPass2: String? = null

When you have private var fields in your view class, it's usually a code smell. Of course sometimes you have to do that for very specific functionality, but you should avoid it as much as possible.

CodePudding user response:

Here's another way you could do this:

private val etEmail get() = findViewById<EditText>(R.id.et_email).text.toString().trim()
private val etPass get() = findViewById<EditText>(R.id.pass).text.toString()
private val etPass2 get() = findViewById<EditText>(R.id.et_pass2).text.toString()

So they still behave like properties and you don't have to change your click listener code, but every time you read them they look up the current contents of each EditText. They're basically lookup functions.

Because they call findViewById you have to make sure you only access them after the Activity has its view set up (e.g. through setContentView) - but since you're only reading those properties through button clicks, which definitely can only happen after that, you're good. It's similar to lateinit - you just have to be mindful of when the property is read, and make sure that it will be safe to do so at that point

CodePudding user response:

Since you need to cast EditText to toString (So it will never be null)

For myself I don't see the point to use .isNullOrEmpty() instead I will use isEmpty() so the value you pass can't not be null to make it less confusion.

Please consider Using ViewBinding It would make your code more clean and more easy to manage

In your case I would do something like this

class SignUp : AppCompatActivity() {
private lateinit var auth: FirebaseAuth
private lateinit var binding: ActivitySignUpBinding
private fun String.isEmailValid() : Boolean = android.util.Patterns.EMAIL_ADDRESS.matcher(this).matches()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivitySignUpBinding.inflate(layoutInflater)
    setContentView(binding.root)
    // Initialising
    auth = Firebase.auth
    //Dialog
    val dialog = Dialog(this)
    dialog.setContentView(R.layout.custom_dialog)


    binding.btn_create.setOnClickListener {
        dialog.show()
        val emailText = binding.et_email.text.toString()
        val passwordText = binding.pass.text.toString()
        val confirmPasswordText = binding.et_pass2.text.toString()
        val result = isValid(emailText,passwordText,confirmPasswordText)
        Toast.makeText(this, result, Toast.LENGTH_SHORT).show()
        if(result == "Done")//todo{}
        dialog.dismiss()
    }

}

private fun isValid(email: String, password: String, confirmPassword: String): String {
    if (email.isEmpty() && password.isEmpty() && confirmPassword.isEmpty()) return "Fill in the blanks"
    if (password != confirmPassword) return "Password do not match"
    if (email.isEmailValid()) return "Done"

    return "Invalid Email"
}

}

  • Related