skip to Main Content

I’m a beginner in flutter. Here I want to create a ListView.builder

ListView.builder(
           shrinkWrap: true,
           itemCount: filterMangaList.length,
           itemBuilder: (context, index) {
             return ListTile(
                 title: Text(filterMangaList[index]['title']),
                 );
           },
         ),

where filterMangaList looks like this
[[{total_chapter: 361, pic: https://images.pexels.com/photos/213780/pexels-photo-213780.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500, title: My Hero Academia}], [{total_chapter: 700, pic: https://images.pexels.com/photos/213780/pexels-photo-213780.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500, title: Naruto}]].

I obtain filterMangaList with this function

Future getFavMangas() async {
    final favMangasList =
        await firestore.collection("users").doc(user.uid).get().then((value) {
      return value.data()?["fav_manga"];
    });

    for (var i in favMangasList) {
      final mangas = await FirebaseFirestore.instance
          .collection('mangas')
          .where('title', isEqualTo: i)
          .get();
      final filterManga = mangas.docs.map((doc) => doc.data()).toList();
      filterMangaList.add(filterManga);
      setState(() {
        filterMangaList;
      });
    }
    print(filterMangaList);}

but nothing append.
I know it’s a problem of scop, because when i print filterMangaList in my initState, it’s empty, but i don’t know how to resolve it. The value of filterMangaList is not update with the result of the function. I try replace setState to a return, but the same.

Here my full code


import 'dart:convert';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:mugiwarapp/init_profil.dart';

class ProfilPage extends StatefulWidget {
  ProfilPage({Key? key}) : super(key: key);

  @override
  State<ProfilPage> createState() => _ProfilPageState();
}

class _ProfilPageState extends State<ProfilPage> {
  FirebaseFirestore firestore = FirebaseFirestore.instance;
  List favMangasList = [];

  List filterMangaList = [];
  @override
  void initState() {
    getFavMangas();
    print(filterMangaList);
    super.initState();
  }

  Future getFavMangas() async {
    final favMangasList =
        await firestore.collection("users").doc(user.uid).get().then((value) {
      return value.data()?["fav_manga"];
    });

    for (var i in favMangasList) {
      final mangas = await FirebaseFirestore.instance
          .collection('mangas')
          .where('title', isEqualTo: i)
          .get();
      final filterManga = mangas.docs.map((doc) => doc.data()).toList();
      filterMangaList.add(filterManga);
      setState(() {
        filterMangaList;
      });
    }
    print(filterMangaList);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Padding(
      padding: const EdgeInsets.only(left: 30, right: 30),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const SizedBox(
            height: 40,
          ),

          Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              // IconButton(
              //     onPressed: () {
              //       Navigator.pop(context);
              //     },
              //     icon: const Icon(Icons.arrow_back)),
              const Text(
                "Profil",
                style: TextStyle(
                    color: Colors.white,
                    fontSize: 30,
                    fontWeight: FontWeight.bold),
              ),
              TextButton(
                  onPressed: () {},
                  child: const Text(
                    "Editer",
                    style: TextStyle(color: Colors.white),
                  ))
            ],
          ),
          const SizedBox(
            height: 40,
          ),
          Row(children: [
            Column(children: [
              const SizedBox(
                  width: 160,
                  child: Text("Pseudo",
                      textAlign: TextAlign.start,
                      style: TextStyle(
                          color: Colors.white,
                          fontSize: 25,
                          fontWeight: FontWeight.bold))),
              const SizedBox(
                height: 10,
              ),
              SizedBox(
                  width: 160,
                  child: Row(children: const [
                    Text(
                      "Membre depuis ",
                      style: TextStyle(fontSize: 11),
                    ),
                    Text(
                      "Janvier 2021",
                      style:
                          TextStyle(fontSize: 11, fontWeight: FontWeight.bold),
                    )
                  ])),
              const SizedBox(
                height: 15,
              ),
              SizedBox(
                  width: 160,
                  child: Row(children: const [
                    Text(
                      "Manga préféré : ",
                      style: TextStyle(fontSize: 11),
                    ),
                    Text(
                      "Berserk",
                      style:
                          TextStyle(fontSize: 11, fontWeight: FontWeight.bold),
                    )
                  ])),
              SizedBox(
                  width: 160,
                  child: Row(children: const [
                    Text(
                      "Anime préféré : ",
                      style: TextStyle(fontSize: 11),
                    ),
                    Text(
                      "One Piece",
                      style:
                          TextStyle(fontSize: 11, fontWeight: FontWeight.bold),
                    )
                  ])),
              const SizedBox(
                height: 10,
              ),
              SizedBox(
                  width: 160,
                  child: Row(children: const [
                    Text(
                      "à jour sur ",
                      style: TextStyle(fontSize: 11),
                    ),
                    Text(
                      "2 ",
                      style:
                          TextStyle(fontSize: 11, fontWeight: FontWeight.bold),
                    ),
                    Text(
                      "mangas",
                      style: TextStyle(
                        fontSize: 11,
                      ),
                    )
                  ])),
              SizedBox(
                  width: 160,
                  child: Row(children: const [
                    Text(
                      "à jour sur ",
                      style: TextStyle(fontSize: 11),
                    ),
                    Text(
                      "3 ",
                      style:
                          TextStyle(fontSize: 11, fontWeight: FontWeight.bold),
                    ),
                    Text(
                      "animes",
                      style: TextStyle(
                        fontSize: 11,
                      ),
                    )
                  ])),
            ]),
            const SizedBox(
              width: 10,
            ),
            SizedBox(
              height: 125,
              width: 125,
              child: ClipRRect(
                borderRadius: BorderRadius.circular(30),
                child: Image.network(
                  'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg',
                  fit: BoxFit.fill,
                ),
              ),
            )
          ]),
          const SizedBox(
            height: 50,
          ),
          Text(
            'Recommendations',
            style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
          ),
          // SizedBox(
          //     child: ListView.builder(
          //   physics: ClampingScrollPhysics(),
          //   shrinkWrap: true,
          //   scrollDirection: Axis.horizontal,
          //   itemCount: 3,
          //   itemBuilder: (BuildContext context, int index) {
          //     return ListTile(
          //       title: Text("Titre recommandations"),
          //       tileColor: Colors.red,
          //     );
          //   },
          // )),
          const Text(
            'Continuer à lire',
            style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
          ),
          ListView.builder(
            shrinkWrap: true,
            itemCount: filterMangaList.length,
            itemBuilder: (context, index) {
              return ListTile(
                  title: Text(filterMangaList[index]['title']),
                  );
            },
          ),
        ],
      ),
    ));
  }
}

It’s probably a little thing but i can’t figure how to solve it.
I’m open to all advice.
Thanks in advance !

Sorry for my english, french here.

2

Answers


  1. Chosen as BEST ANSWER

    Ok, so for those who want to know the answer. I used a FutureBuilder like this

    FutureBuilder(
                  future: getFavMangas(),
                  builder: (context, AsyncSnapshot future) {
                    if (!future.hasData)
                      return Container();
                    else {
                      var filterMangaList = future.data;
                      print(filterMangaList);
                      return ListView.builder(
                        shrinkWrap: true,
                        itemCount: filterMangaList.length,
                        itemBuilder: (BuildContext context, int index) {
                          return Container(
                            child: Text(filterMangaList.toString()),
                          );
                        },
                      );
                    }
                  }),
    

    (the ListView.builder is not finish)

    but here, I had an infinite loop. So I change the setState to a return in my function and change the type to List

    Future<List> getFavMangas() async {
        var value = await firestore.collection("users").doc(user.uid).get();
        final favMangasList = value.data()?["fav_manga"];
        filterMangaList.clear();
    
        for (var i in favMangasList) {
          final mangas = await FirebaseFirestore.instance
              .collection('mangas')
              .where('title', isEqualTo: i)
              .get();
          final filterManga = mangas.docs.map((doc) => doc.data()).toList();
          filterMangaList.add(filterManga);
        }
        return filterMangaList;
      }
    

    and change my initState to this

    late Future<List<dynamic>> _filterMangaList;
    
      @override
      void initState() {
        _filterMangaList = getFavMangas();
        super.initState();
      }
    

    so in result I have all my filterMangaList that is displaied, like I wanted (for now).

    Not clean I think but it works !


  2. Your problem is in this function:

    Future getFavMangas() async {
        final favMangasList =
            await firestore.collection("users").doc(user.uid).get().then((value) {
          return value.data()?["fav_manga"];
        });
    
        for (var i in favMangasList) {
          final mangas = await FirebaseFirestore.instance
              .collection('mangas')
              .where('title', isEqualTo: i)
              .get();
          final filterManga = mangas.docs.map((doc) => doc.data()).toList();
          filterMangaList.add(filterManga);
          setState(() {
            filterMangaList;
          });
        }
        print(filterMangaList);
      }
    

    when you call return value.data()?["fav_manga"] function break and wont go for other code in that function, So change it to this:

    Future getFavMangas() async {
        var value =
            await firestore.collection("users").doc(user.uid).get()
        final favMangasList = value.data()?["fav_manga"];
            
    
        for (var i in favMangasList) {
          final mangas = await FirebaseFirestore.instance
              .collection('mangas')
              .where('title', isEqualTo: i)
              .get();
          final filterManga = mangas.docs.map((doc) => doc.data()).toList();
          filterMangaList.add(filterManga);
          setState(() {
            filterMangaList;
          });
        }
        print(filterMangaList);
      }
    

    Update:It is not ok to use async function inside initState, so you should use FutureBuilder, wrap your sacffold’s body with FutureBuilder like this:

    body: FutureBuilder<List>(
          future: getFavMangas(),
          builder: (context, snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.waiting:
                return Text('Loading....');
              default:
                if (snapshot.hasError) {
                  return Text('Error: ${snapshot.error}');
                } else {
                  List data = snapshot.data ?? [];
                 
                  return Padding(
                     ....(rest of the widgets)
                     ListView.builder(
                      itemBuilder: (context, index) {
                        return Column(children: [
                          Text(data[index]['title'] ?? ""),
                        ]);
                      },
                      itemCount: data.length,
                    ),
                  );
                }
            }
          },
        ),
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search