2 Dropdown dynmic : bug de données identiques

Bonjour !

Après avoir un temps fou sur un problème qui me semble assez standard, je finis par poster dans l’espoir d’avoir vos éclairages.

Ainsi, dans un formulaire, je dois charger des DropDownMenu avec des données dynamic, sachant que bien sûr le premier menu conditionne l’affichage de la seconde liste. Les symptômes :

  • La première fois tout fonctionne à la perfection.
  • J’ai testé mes fonctions de viewmodel : elles répondent toujours sans problèmes

Mais lorsque je change la valeur du premier menu, j’ai un bug sur l’affichage de la seconde liste car Flutter m’indique que les données ne sont pas uniques, pourtant il me « semble » que je décharge correctement… évidemment ce n’est pas le cas !

Ainsi ma view :

Expanded(
                          flex: 4,
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              DropdownButtonFormField(
                                items: widget.viewModel.userListGenre,
                                onChanged: _setgenre,
                                decoration: InputDecoration(
                                  labelText: S.of(context).genre,
                                ),
                              ),
                              widget.viewModel.genreIDSelected > 0
                                  ? FutureBuilder<
                                          List<DropdownMenuItem<dynamic>>>(
                                      future:
                                          widget.viewModel.getAllSubGenreVM(),
                                      initialData: [],
                                      builder: (context, snapshot) {
                                        if (snapshot.hasError) {
                                          return Center(
                                            child: Text(S.of(context).error),
                                          );
                                        } else if (!snapshot.hasData) {
                                          return const Center(
                                            child: CircularProgressIndicator(),
                                          );
                                        } else {
                                          //data = snapshot.data;
                                          return DropdownButtonFormField(
                                            items: snapshot.data,
                                            onChanged: _setSSgenre,
                                            decoration: InputDecoration(
                                              labelText: S.of(context).subgenre,
                                            ),
                                          );
                                        }
                                      })
                                  : const SizedBox(),
                              DropdownButtonFormField(
                                items: dropdown,
                                onChanged: _setIntensity,
                                decoration: InputDecoration(
                                  labelText: S.of(context).intensiy,
                                ),
                              ),
                              DropdownButtonFormField(
                                items: dropdown,
                                onChanged: _setFame,
                                decoration: InputDecoration(
                                  labelText: S.of(context).famous,
                                ),
                              ),
                              DropdownButtonFormField(
                                items: widget.viewModel.userListLang,
                                onChanged: _setLang,
                                decoration: InputDecoration(
                                  labelText: S.of(context).language,
                                ),
                              ),
                            ],
                          ),
                        ),

Puis mes fonction de state, sachant currentGenreMusic est la valeur du 1er menu et currentSSGenreMusic la seconde. Les valeurs du premier menu étant toujours identique, elles sont chargées un seule fois au build avec un initState, ce qui n’est évidemment pas possible avec la seconde, d’où l’usage du FutureBuilder.

  _setgenre(value) {
    setState(() {
      currentSSGenreMusic = null;
      widget.viewModel.userListSSGenre = [];
      widget.viewModel.genreIDSelected = value;
      currentGenreMusic = value;
      print("_setgenre = $currentGenreMusic");
    });
  }

  _setSSgenre(value) {
    print("sous genre = $value");
    setState(() {
      currentSSGenreMusic = value;
    });
  }

Je décharge la liste chargée dans le second DropDown ( userListSSGenre ) ainsi que le value dès le choix du premier menu.

En gros je ne parviens pas à réinitialiser le second menu pour que cette erreur disparaisse :

"There should be exactly one item with [DropdownButtonFormField]'s value: 2. \nEither zero or 2 or
more [DropdownMenuItem]s were detected with the same value"
The relevant error-causing widget was:

Merci beaucoup !

Finalement, je m’en suis sorti en gérant le paramètre isDense :

 return DropdownButtonFormField(
                                            items: snapshot.data,
                                            value: currentSSGenreMusic,
                                            onChanged: _setSSgenre,
                                            isDense:
                                                currentSSGenreMusic == null,
                                            decoration: InputDecoration(
                                              labelText: S.of(context).subgenre,
                                            ),
                                          );

et en reset la currentSSGenreMusic via le state.

Juste pour info, car je me suis beaucoup pris la tête avec ce problème : isDense n’y est évidemment pour rien, lorsqu’on cherche à travailler avec deux menus, il faut impérativement Reset la Value, sans quoi elle demeure lors du prochain chargement. Ainsi, même si la nouvelle liste est correct, il reste une Value sélectionnée et le menu plante…