Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter function parameter pass by reference

Tags:

flutter

dart

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?

like image 465
Vali Avatar asked Mar 14 '19 09:03

Vali


1 Answers

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.

like image 128
thedarthcoder Avatar answered Oct 07 '22 02:10

thedarthcoder