Home > Software design >  FutureBuilder not updated after setState call
FutureBuilder not updated after setState call

Time:09-11

I have a FutureBuilder that returns a ListViewBuilder in a class.

When loading the class the FutureBuilder loads the future which is a call to a API, then the ListView shows the received items inside Cards.

It is working fine, at this moment there are three items that should and are showed.

Then I am trying to verify if the class is updated when executing setState at a button click action. I am manually adding or removing items from the database that is called from the API, but clicking on the refres button after adding/removing items from the database, the list is not changing.

Here you have the code:

                  Container(
                    height: 120,
                    child:
                    FutureBuilder(
                      future: fetchFotosInformesIncidenciasTodos(
                          widget.informeActual.codigo),
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          List<dynamic>? filteredList =
                              snapshot.data as List?;
                          filteredList ??= [];

                          listaFotosInformeIncidenciasActual =
                              filteredList;

                          WidgetsBinding.instance
                              .addPostFrameCallback((t) {
                            setState(() {
                              numeroFotosSubidas =
                                  filteredList!.length  
                                      numeroFotosSubidasAhora;
                            });
                          });

                          return ListView.builder(
                            scrollDirection: Axis.horizontal,
                            itemCount: filteredList.length,
                            shrinkWrap: false,
                            itemBuilder: (BuildContext context, index) {
                              FotoInformeIncidenciasModelo foto =
                                  filteredList![index];

                              var urlFoto = Constantes
                                      .adminInformesIncidenciasUrl  
                                  foto.archivo;

                              return GestureDetector(
                                  onTap: () {
                                    print("pulsada foto ${foto.id}");
                                  },
                                  child: Card(
                                    elevation: 6,
                                    child: (Column(
                                      children: [
                                        Image.network(
                                          urlFoto,
                                          width: 60,
                                          height: 80,
                                        ),
                                      ],
                                    )),
                                  ));
                            },
                          );
                        }

                        return Image.asset(
                          "imagenes/vacio.png",
                          fit: BoxFit.contain,
                        );
                      },
                    ),
                  ),

And here the refresh button:

    InkWell(
      onTap: (){
        setState(() {
          print("refrescando");
        });
      },
        child: Text("refrescar")),

I would like to know why is the call to setState not forcing to update the FutureBuilder and the ListView Builder

CodePudding user response:

The future function fetchFotosInformesIncidenciasTodos(widget.informeActual.codigo) which is being called directly from the Future block. You need to make an instance of the future and invoke the same whenever you want a new request for the future eg.

Future<Response> _futureFun;
....

 @override
 void initState() {
   super.initState();
   _futureFun = 
     fetchFotosInformesIncidenciasTodos(widget.informeActual.codigo)
  }


 _futureFun = fetchFotosInformesIncidenciasTodos(widget.informeActual.codigo){}


 @override
 Widget build(BuildContext context) {

 ....

   FutureBuilder<Response>(
        future: _futureFun,
   ....

 }

And to refresh the data again, just call the function fetchFotosInformesIncidenciasTodos(widget.informeActual.codigo) again and there is not need to setState.

  • Related