Flutter: DropdownButton is not working, I load the data but it does not appear in the interface

986

It seems fine.

One idea.. The Form may be loading before setInitRegister finishes.

Can you try this?:

class _RegisterState extends State<Register> {
  final _formKey = GlobalKey<FormState>();
  bool _autoValidate = false;
  ...
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: FutureBuilder<Map>(
          future: setInitRegister(),
          builder: (BuildContext context, snapshot) {
            if (!snapshot.hasData) {
              // while data is loading:
              return Center(
                child: CircularProgressIndicator(),
              );
            } else {
              // data loaded:
              final Map data = snapshot.data;
              final List<DropdownMenuItem<String>> countryList = data['countryList'];
              final List<DropdownMenuItem<String>> codeList = data['codeList'];
              return Center(
                child: SafeArea( ... ),
              );
            }
          },
        ),
  }
  Future<Map> setInitRegister() async {
    List<DropdownMenuItem<String>> countryList;
    List<DropdownMenuItem<String>> codeList;
    Map result = {};
    objcifrado = Funcionesgenerales();
    List<Paises> objpaises = await objcifrado.getCountriesData();
    passwordprefix = await objcifrado.getPasswordprefix();
    urlapi = await objcifrado.getPasswordUrl();
    objdata = await objcifrado.getPhoneData();
    objapi = Requestapi(url: urlapi, passwordprefix: passwordprefix);
    countryList = loadcountryList(objpaises);// Load countries list
    codeList = loadccodeList(objpaises);// Load phone code list
    result['countryList'] = countryList;
    result['codeList'] = codeList;
    return result;
  }
  //From the array of countries I add elements to countrylist
  List<DropdownMenuItem<String>> loadcountryList(List<Paises> objpaises) {
    List<DropdownMenuItem<String>> countryList = [];
    objpaises.forEach((element) {
      countryList.add(new DropdownMenuItem(
        child: new Text(element.name),
        value: element.countrycode,
      ));
    });
    return countryList;
  }
  //From the array of countries I add elements to codelist
  List<DropdownMenuItem<String>> loadccodeList(List<Paises> objpaises) {
    List<DropdownMenuItem<String>> codeList = [];
    objpaises.forEach((element) {
      codeList.add(new DropdownMenuItem(
        child: new Text(element.phonecode),
        value: element.countrycode,
      ));
    });
    return codeList;
  }
}

You can also check this post in which I based most of my answer.

A slightly better solution would be to move the future call into initState (again, see the post); but I tried to keep it simple first.

Let me know how it goes!

Share:
986
Rivero Felipe
Author by

Rivero Felipe

Updated on December 22, 2022

Comments

  • Rivero Felipe
    Rivero Felipe less than a minute

    I am working on a mobile application with Flutter. I am creating a registration page that contains two fields "select" or "DropdownButton".

    A DropdownButton contains a list of countries by names. The other DropdownButton is a list of country phone codes.

    The expected functionality is when I select a country, in the DropdownButton of telephone codes it is updated immediately with the telephone code of the selected country.

    Here are the variables I use:

    List<DropdownMenuItem<String>> countryList = [];//  Country list
      List<DropdownMenuItem<String>> codeList = [];//  Code list
      String selectedcountries; // Value of the selected country
      String selectedcode; // value of the selected phone code
    

    Here is the DropdownButton Widget for countries:

    DropdownButton(
                            isExpanded: true,
                            hint: Text('Pais'),
                            items: countryList, // list of countries
                            value: selectedcountries, // value selected of countries
                            onChanged: (value) {
                              setState(() {
                                selectedcountries = value;// here I updated the value of countries
                                selectedcode = value; // here I updated the value of phone code
                              });
                            },
                            style: TextStyle(color: Colors.grey[600], fontSize: 22),
                          ),
    

    Here is the DropdownButton Widget for phone code:

    DropdownButton(
                                hint: Text('Cod.'),
                                items: codeList, // list of phone codes
                                value: selectedcode, // value of selected phone code
                                onChanged: (value) {
                                  setState(() {
                                    selectedcode = value;// Here i updated the value of phone code
                                  });
                                },
                                style: TextStyle(
                                    color: Colors.grey[600], fontSize: 22),
                              ),
    

    I created a function that loads all the data I need to perform the functions associated with user registration:

      Future<void> setInitRegister() async {
        objcifrado = Funcionesgenerales();
        objpaises = await objcifrado.getCountriesData();
        passwordprefix = await objcifrado.getPasswordprefix();
        urlapi = await objcifrado.getPasswordUrl();
        objdata = await objcifrado.getPhoneData();
        objapi = Requestapi(url: urlapi, passwordprefix: passwordprefix);
        loadcountryList();// Load countries list
        loadccodeList();// Load phone code list
        print(countryList);
      }
    

    Next, there are the functions that load the list of countries and telephone codes.

    //From the array of countries I add elements to countrylist
      void loadcountryList() {
        objpaises.forEach((element) {
          countryList.add(new DropdownMenuItem(
            child: new Text(element.name),
            value: element.countrycode,
          ));
        });
      }
    //From the array of countries I add elements to codelist
      void loadccodeList() {
        objpaises.forEach((element) {
          codeList.add(new DropdownMenuItem(
            child: new Text(element.phonecode),
            value: element.countrycode,
          ));
        });
      }
    

    The setInitRegister function called it before rendering like so: enter image description here

    Here is the user registration screen, when I click on the select "country" (Country).

    Nothing happens. Also nothing happens when I touch the select of phone code (Cod.)

    enter image description here

    Checking the console, I print the lists. Apparently the data arrives well and without problems.

    enter image description here

    Here is the full class of user registration

    import 'package:flutter/material.dart';
    import 'package:pinfamilyapp/pages/funciones.dart';
    import 'package:pinfamilyapp/pages/phonedata.dart';
    import 'package:pinfamilyapp/services/servicios.dart';
    class Register extends StatefulWidget {
      @override
      _RegisterState createState() => _RegisterState();
    }
    class _RegisterState extends State<Register> {
      final _formKey = GlobalKey<FormState>();
      bool _autoValidate = false;
      bool obscureText = true;
      bool obscureText2 = true;
      String name;
      String apellidos;
      String telefono;
      String correo;
      String clave;
      String clave2;
      String passwordprefix;
      String urlapi;
      List<Paises> objpaises = [];
      Funcionesgenerales objcifrado;
      Requestapi objapi;
      List<DropdownMenuItem<String>> countryList = []; //  Country list
      List<DropdownMenuItem<String>> codeList = []; //  Code list
      Phonedata objdata;
      String selectedcountries; // Value of the selected country
      String selectedcode; // value of the selected code
      @override
      Widget build(BuildContext context) {
        setInitRegister();
        return Scaffold(
          backgroundColor: Colors.white,
          body: SafeArea(
              child: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                SizedBox(height: 20),
                Container(
                  padding: EdgeInsets.fromLTRB(5, 10, 10, 10),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      FlatButton(
                          onPressed: () {
                            Navigator.pushReplacementNamed(context, "/home");
                          },
                          child: Icon(
                            Icons.arrow_back,
                            color: Colors.blue[900],
                            size: 25,
                          )),
                      SizedBox(width: 30),
                      Text(
                        "Regístrarse",
                        style: TextStyle(
                            color: Colors.blue[900],
                            fontSize: 22,
                            fontWeight: FontWeight.bold),
                      )
                    ],
                  ),
                ),
                SizedBox(height: 10),
                Padding(
                  padding: EdgeInsets.fromLTRB(30, 5, 30, 5),
                  child: Form(
                      key: _formKey,
                      autovalidate: _autoValidate,
                      child: Column(
                        children: <Widget>[
                          TextFormField(
                              onChanged: (val) {
                                setState(() {
                                  name = val;
                                });
                              },
                              decoration: InputDecoration(hintText: "Nombres"),
                              style:
                                  TextStyle(color: Colors.grey[600], fontSize: 22),
                              validator: (value) {
                                if (value.isEmpty) {
                                  return 'Por favor ingrese su(s) Nombre(s)';
                                } else {
                                  if (value.length < 4)
                                    return 'El nombre debe tener mas de 4 caracteres';
                                }
                                return null;
                              }),
                          SizedBox(height: 10),
                          TextFormField(
                              onChanged: (val) {
                                setState(() {
                                  apellidos = val;
                                });
                              },
                              decoration: InputDecoration(hintText: "Apellidos"),
                              style:
                                  TextStyle(color: Colors.grey[600], fontSize: 22),
                              validator: (value) {
                                if (value.isEmpty) {
                                  return 'Por favor ingrese su(s) Apellido(s)';
                                } else {
                                  if (value.length < 4)
                                    return 'El apellido debe tener mas de 4 caracteres';
                                }
                                return null;
                              }),
                          SizedBox(height: 10),
                          DropdownButton(
                            isExpanded: true,
                            hint: Text('Pais'),
                            items: countryList,
                            value: selectedcountries,
                            onChanged: (value) {
                              setState(() {
                                selectedcountries = value;
                                selectedcode = value;
                              });
                            },
                            style: TextStyle(color: Colors.grey[600], fontSize: 22),
                          ),
                          SizedBox(height: 10),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            verticalDirection: VerticalDirection.down,
                            crossAxisAlignment: CrossAxisAlignment.end,
                            children: <Widget>[
                              DropdownButton(
                                hint: Text('Cod.'),
                                items: codeList,
                                value: selectedcode,
                                onChanged: (value) {
                                  setState(() {
                                    selectedcode = value;
                                  });
                                },
                                style: TextStyle(
                                    color: Colors.grey[600], fontSize: 22),
                              ),
                              SizedBox(
                                width: 275,
                                child: TextFormField(
                                    onChanged: (val) {
                                      setState(() {
                                        telefono = val;
                                      });
                                    },
                                    decoration:
                                        InputDecoration(hintText: "Telefono"),
                                    keyboardType: TextInputType.phone,
                                    style: TextStyle(
                                        color: Colors.grey[600], fontSize: 22),
                                    validator: (value) {
                                      if (value.isEmpty) {
                                        return 'Por favor ingrese su telefono';
                                      } else {
                                        if (value.length < 8)
                                          return 'El numero de telefono debe tener mas de 8 digitos';
                                      }
                                      return null;
                                    }),
                              ),
                            ],
                          ),
                          SizedBox(height: 10),
                          TextFormField(
                            keyboardType: TextInputType.emailAddress,
                            onChanged: (val) {
                              setState(() {
                                correo = val;
                              });
                            },
                            decoration:
                                InputDecoration(hintText: "Correo electrónico"),
                            style: TextStyle(color: Colors.grey[600], fontSize: 22),
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'Por favor ingrese su correo electrónico';
                              } else {
                                Pattern pattern =
                                    r'^(([^<>()[\]\\.,;:\[email protected]\"]+(\.[^<>()[\]\\.,;:\[email protected]\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
                                RegExp regex = new RegExp(pattern);
                                if (!regex.hasMatch(value)) {
                                  return 'Por favor ingrese un correo electrónico valido';
                                }
                              }
                              return null;
                            },
                          ),
                          SizedBox(height: 10),
                          TextFormField(
                            onChanged: (val) {
                              setState(() {
                                clave = val;
                              });
                            },
                            obscureText: obscureText,
                            decoration: InputDecoration(
                                hintText: "Contraseña",
                                suffixIcon: GestureDetector(
                                  onTap: () {
                                    setState(() {
                                      obscureText = !obscureText;
                                    });
                                  },
                                  child: Icon(obscureText
                                      ? Icons.visibility
                                      : Icons.visibility_off),
                                )),
                            style: TextStyle(color: Colors.grey[600], fontSize: 22),
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'Por favor ingrese su contraseña';
                              } else {
                                Pattern pattern =
                                    r'(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{6,})$';
                                RegExp regex = new RegExp(pattern);
                                if (!regex.hasMatch(value)) {
                                  return 'Por favor ingrese una contraseña valida: \nDebe tener letras y numero, minimo 6 caracteres';
                                }
                              }
                              return null;
                            },
                          ),
                          SizedBox(height: 10),
                          TextFormField(
                            onChanged: (val) {
                              setState(() {
                                clave = val;
                              });
                            },
                            obscureText: obscureText2,
                            decoration: InputDecoration(
                                hintText: "Repetir Contraseña",
                                suffixIcon: GestureDetector(
                                  onTap: () {
                                    setState(() {
                                      obscureText2 = !obscureText2;
                                    });
                                  },
                                  child: Icon(obscureText2
                                      ? Icons.visibility
                                      : Icons.visibility_off),
                                )),
                            style: TextStyle(color: Colors.grey[600], fontSize: 22),
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'Por favor ingrese su contraseña';
                              } else {
                                Pattern pattern =
                                    r'(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{6,})$';
                                RegExp regex = new RegExp(pattern);
                                if (!regex.hasMatch(value)) {
                                  return 'Por favor ingrese una contraseña valida: \nDebe tener letras y numero, minimo 6 caracteres';
                                }
                              }
                              return null;
                            },
                          ),
                          SizedBox(
                            height: 25,
                          ),
                          SizedBox(
                            width: 350,
                            child: ButtonTheme(
                              minWidth: 150.0,
                              height: 50.0,
                              child: RaisedButton(
                                color: Colors.green[500],
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(5.0),
                                ),
                                onPressed: () {
                                  if (_formKey.currentState.validate()) {
                                    // If the form is valid, display a Snackbar.
                                    print(name);
                                  }
                                },
                                child: Padding(
                                  padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
                                  child: Text(
                                    "Registrarse",
                                    style: TextStyle(
                                        color: Colors.white, fontSize: 22),
                                  ),
                                ),
                              ),
                            ),
                          )
                        ],
                      )),
                ),
                SizedBox(
                  height: 10,
                ),
                Container(
                  color: Colors.grey[100],
                  child: Padding(
                    padding: EdgeInsets.fromLTRB(10, 20, 10, 20),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        SizedBox(height: 20),
                        Center(
                          child: Text(
                            "o Iniciar sesión con:",
                            style:
                                TextStyle(fontSize: 20.0, color: Colors.blue[900]),
                          ),
                        ),
                        SizedBox(height: 20),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            ButtonTheme(
                              minWidth: 150.0,
                              height: 50.0,
                              child: RaisedButton(
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(5.0),
                                ),
                                onPressed: () {},
                                color: Colors.blue[900],
                                child: Padding(
                                  padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
                                  child: Text(
                                    "Facebook",
                                    style: TextStyle(
                                        color: Colors.white, fontSize: 22),
                                  ),
                                ),
                              ),
                            ),
                            SizedBox(width: 10),
                            ButtonTheme(
                              minWidth: 150.0,
                              height: 50.0,
                              child: RaisedButton(
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(5.0),
                                ),
                                onPressed: () {},
                                color: Colors.red[500],
                                child: Padding(
                                  padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
                                  child: Text(
                                    "Google +",
                                    style: TextStyle(
                                        color: Colors.white, fontSize: 22),
                                  ),
                                ),
                              ),
                            ),
                          ],
                        ),
                        SizedBox(height: 20)
                      ],
                    ),
                  ),
                ),
                Container(
                  color: Colors.blue[900],
                  height: 70,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text("¿Ya tienes cuenta?",
                          style: TextStyle(color: Colors.white, fontSize: 20)),
                      SizedBox(width: 1),
                      FlatButton(
                          onPressed: () {
                            Navigator.pushReplacementNamed(context, "/home");
                          },
                          child: Text(
                            "Iniciar sesión",
                            style: TextStyle(
                              color: Colors.white,
                              fontSize: 20,
                              decoration: TextDecoration.underline,
                            ),
                          ))
                    ],
                  ),
                )
              ],
            ),
          )),
        );
      }
      Future<void> setInitRegister() async {
        objcifrado = Funcionesgenerales();
        objpaises = await objcifrado.getCountriesData();
        passwordprefix = await objcifrado.getPasswordprefix();
        urlapi = await objcifrado.getPasswordUrl();
        objdata = await objcifrado.getPhoneData();
        objapi = Requestapi(url: urlapi, passwordprefix: passwordprefix);
        loadcountryList();// Load countries list
        loadccodeList();// Load phone code list
        print(countryList);
      }
    //From the array of countries I add elements to countrylist
      void loadcountryList() {
        objpaises.forEach((element) {
          countryList.add(new DropdownMenuItem(
            child: new Text(element.name),
            value: element.countrycode,
          ));
        });
      }
    //From the array of countries I add elements to codelist
      void loadccodeList() {
        objpaises.forEach((element) {
          codeList.add(new DropdownMenuItem(
            child: new Text(element.phonecode),
            value: element.countrycode,
          ));
        });
      }
    }
    

    Any ideas?

  • Rivero Felipe
    Rivero Felipe over 2 years
    Thank you so much. You answer save me. Now its working perfectly.
  • Andres Silva
    Andres Silva over 2 years
    My pleasure! I'm glad it helped.