setState() or markNeedsBuild() called during build Query Widget

0

I have a problem with Graphql Flutter. I am trying to display a search list retrieved with graphql.

But flutter tells me:

This widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.

I added some Future Builder to avoid this kind of issue but unfortunately it doesn't seem to work

this is my code:

Column(
                            children: [
                              Row(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                crossAxisAlignment: CrossAxisAlignment.center,
                                children: <Widget>[
                                  Flexible(
                                    flex: 5,
                                    child: AnimatedContainer(
                                      duration: Duration(milliseconds: 500),
                                      padding: EdgeInsets.symmetric(horizontal: 25),
                                      height: 42.0,
                                      width: width,
                                      decoration: BoxDecoration(
                                        borderRadius:
                                        BorderRadius.circular(20.0),
                                        color: const Color(0xffffffff),
                                        boxShadow: [
                                          BoxShadow(
                                            color: const Color(0x29000000),
                                            offset: Offset(0, 0),
                                            blurRadius: 12,
                                          ),
                                        ],
                                      ),
                                      child: Form(
                                        child: Row(
                                          mainAxisAlignment: MainAxisAlignment.spaceAround,
                                          children: [
                                            Flexible(
                                              flex: 1,
                                              child: Container(
                                                width: 17.0,
                                                height: 17.0,
                                                decoration: BoxDecoration(
                                                  image: DecorationImage(
                                                    image: const AssetImage(
                                                        'assets/images/XDSearch.png'),
                                                    fit: BoxFit.cover,
                                                  ),
                                                ),
                                              ),
                                            ),
                                            Flexible(
                                              flex: 6,
                                              child: TextFormField(
                                                onChanged: (value){
                                                  setState(() {
                                                    textSearch = value;
                                                  });
                                                },
                                                keyboardType: TextInputType.emailAddress,
                                                decoration: const InputDecoration(
                                                    focusedBorder: InputBorder.none,
                                                    enabledBorder: InputBorder.none,
                                                    errorBorder: InputBorder.none,
                                                    disabledBorder: InputBorder.none,
                                                    border: InputBorder.none,
                                                    hintText: 'Recherche'
                                                ),
                                                style: TextStyle(
                                                  fontFamily: 'Roboto',
                                                  fontSize: 16,
                                                  color: const Color(0x8c000000),
                                                  fontWeight: FontWeight.w700,
                                                ),
                                                textAlign: TextAlign.left,
                                                focusNode: _focus,
                                              ),
                                            )
                                          ],
                                        ),
                                      ),
                                    ),
                                  ),
                                  clickOnBar == false ? Flexible(
                                    flex: 1,
                                    child: Column(
                                      mainAxisAlignment: MainAxisAlignment.center,
                                      crossAxisAlignment: CrossAxisAlignment.end,
                                      children: [
                                        Container(
                                          width: 30.0,
                                          height: 30.0,
                                          margin: EdgeInsets.fromLTRB(0, 0, 0, 0),
                                          decoration: BoxDecoration(
                                            borderRadius: BorderRadius.circular(15.0),
                                            image: DecorationImage(
                                              image: const AssetImage('assets/images/XDProfil.png'),
                                              fit: BoxFit.fill,
                                            ),
                                          ),
                                        )
                                      ],
                                    ),
                                  ) : Container()
                                ],
                              ),
                              textSearch != null && textSearch != 'undefined' && textSearch.isNotEmpty  ? FutureBuilder(
                                  builder: (context, projectSnap) {
                                    return Query(
                                      options: QueryOptions(
                                          documentNode: gql("""
                                            query getListSearch(\$text : String!){
                                              listSearchProPages(text: \$text) {
                                                categorie {
                                                  idCat
                                                  title
                                                }
                                                subCat {
                                                  idSubCat
                                                  title
                                                }
                                                pagePro {
                                                  idPagesPro
                                                  title
                                                }
                                              }
                                            }
                                          """
                                          ),
                                          variables: <String, dynamic>{
                                            "text": textSearch,
                                          },
                                          pollInterval: 10
                                      ),
                                      builder: (QueryResult result, {VoidCallback refetch, FetchMore fetchMore}){
                                        print(result);

                                        if (result.hasException) {
                                          return Text(result.exception.toString());
                                        }
                                        if (result.loading) {
                                          return Text('Loading');
                                        }

                                        var tmpObject = {
                                          "categorie": result.data['listSearchProPages'].first['categorie'],
                                          "subCat":  result.data['listSearchProPages'].first['subCat'],
                                          "pagePro":  result.data['listSearchProPages'].first['pagePro'],
                                        };

                                        return FutureBuilder(
                                            future: updateListSearch(tmpObject),
                                            builder: (context, projectSnap){
                                              if(tmpObject.length > 0) {
                                                ListView.builder(
                                                    itemCount: tmpObject.length,
                                                    itemBuilder: (context, index) {
                                                      print(tmpObject);
                                                      final repository = tmpObject[index];
                                                      print(repository["categorie"]
                                                          .first['title']);
                                                      return Text(
                                                          repository["categorie"]
                                                              .first['title']);
                                                    }
                                                );
                                              }else {
                                                return Container();
                                              }
                                              return Container();
                                            }
                                        );
                                      },
                                    );
                                  }
                              ) : Container()
                            ],
                          ),

Do you have the solution ?

flutter
asked on Stack Overflow Oct 20, 2020 by bchoisy

1 Answer

0

Please do not create a new future on every call of the build method as you do now.

You need to create a future once (or maybe more often, but certainly not on every build) and then use that future in your build method:

Create a variable of your future type in your state class.

In your initState method, create the future, by assigning the result of updateListSearch(tmpObject) to your variable.

In your build method, use the variable as your parameter for the future in the FutureBuilder.

answered on Stack Overflow Oct 21, 2020 by nvoigt

User contributions licensed under CC BY-SA 3.0