15

I do question regarding Dart and Flutter. So I'm trying to refactor some code and I'm stuck in a referencing problem.

class _LoginPageState extends State<LoginPage> {
  String _email;
  String _password;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: new AppBar(
          title: new Text("Login Page"),
        ),
        body: new Container(
          padding: new EdgeInsets.all(16),
          child: new Form(
              child: new Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: buildInputs()
              )),
        ));
  }

  Widget buildInput(String label, String val) {
    return new TextFormField(
      decoration: new InputDecoration(
        labelText: label,
      ),
      validator: (value) => value.isEmpty ? "$label can't be empty" : null,
      onSaved: (value) => val = value,
    );
  }

  List<Widget> buildInputs() {
    return [
      buildInput("Email", this._email),
      buildInput("Password", this._password),
    ];
  }
}

I'm trying to create a function called buildInput which will take 2 parameters, one will be my label from my form and the second one will be the actual variable which I want to modify. Now here is the tricky part, for some reason I have no idea why... but my variable is never going to set with the correct value, and it is always null.

Any idea how can I pass a parameter with a function in order to modified in the body of the function and the parameter to stay medicated and after the function call is done?

1 Answer 1

4

Since you are using the _email and _password variables in the same class, why use an extra parameter? You can just do something like:

  Widget buildInput(String label) {
    return new TextFormField(
      decoration: new InputDecoration(
        labelText: label,
      ),
      validator: (value) => value.isEmpty ? "$label can't be empty" : null,
      onSaved: (value) => this._email = value,
    );
  }

Also, the dart language does not support passing primitives by reference so they will be always passed by value. If at all you need to pass by reference then you will need to wrap the _email and _password variables inside a separate model class and pass an object of that class to the buildInputs() function.

You can refer to this question for more details on passing by reference in Dart. Hope this helps!

UPDATE:

If you need to use only a single function for the TextField then there is a workaround. You can do something like this:

  Widget buildInput(String label, String val) {
    return new TextFormField(
      decoration: new InputDecoration(
        labelText: label,
      ),
      validator: (value) => value.isEmpty ? "$label can't be empty" : null,
      onSaved: (value) {
        if(val == "email")
          this._email = value;
        else if(val == "password")
          this._password = value;
      }
    );
  }

And you can call the function like this:

  List<Widget> buildInputs() {
    return [
      buildInput("Email", "email"),
      buildInput("Password", "password"),
    ];
  }

This is just one way to check if the data is an email or a password. You can also achieve the same with a bool variable or using enum.

Sign up to request clarification or add additional context in comments.

4 Comments

But this is exactly what I don't want to do, this is exactly the opposite of what I want to do. My idea was to have ONE function, not to use TWO with duplicate pieces of code that are doing the exact same thing with the only diff been the actually variable.
There might be a small workaround for the thing that you need. You can use the val argument to check if the text is an email or a password. I'll update my answer with another example.
You cannot pass a variable by reference. There needs to be separate assignments to _email and _password in your code, because each assignment can only assign to one of them. You can then fiddle with how to choose which assignment to use, but there needs to be two separate assignments somewhere. You can also use pass a single function as the argument, (String value) { this._email = value; } or (String value) { this._password = value; }, and then call the passed function in onSave (or use it directly as the value for the onSave parameter).
this keyword is undefined.. So, I used class_name().variable_name. Is it best practice?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.