Home > Enterprise >  flutter: lateinitializationerror field 'listResult' has not been initialized, on retrievin
flutter: lateinitializationerror field 'listResult' has not been initialized, on retrievin

Time:07-03

I'm trying to fetch names of folders from cloud storage, loop over them and add them to a list and later use that list in a listview builder. I would also like to ask you guys if this is the correct way of getting the names of folders from firebase storage. Thanks in advance if you had time to read this! My firebase structure: firebase cloud stirage structure

Below is my model class:

class FirebaseFolder {
  final Reference ref;
  final String name;
  final String url;

  const FirebaseFolder({
    required this.ref,
    required this.name,
    required this.url,
  });
}

Below is my dashboard code where am implementing it:

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

  @override
  State<DashBoard> createState() => _DashBoardState();
}

class _DashBoardState extends State<DashBoard> {
  late List<String> folderYear = [];
  late Future<List<FirebaseFolder>> listResult;


  @override
  void initState() {
    super.initState();
    getFolders();
    }
  Future<List<String>> getFolders() async {
    final storageRef = FirebaseStorage.instance.ref().child("front end");
    final listResult = await storageRef.listAll();
    for (var prefix in listResult.prefixes) {
      folderYear.add(prefix.name);
    }
    return folderYear;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: kAppBar('DashBoard'),
      body: FutureBuilder<List<FirebaseFolder>>(
        future: listResult,
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return const Center(
                child: spinkitLines,
              );
            default:
              final folders = snapshot.data;
              return Column(
                children: [
                  const SizedBox(
                    height: 30.0,
                  ),
                  const Center(
                    child: Text(
                      'Tap to choose semester',
                      style: kPlaceholderStyle,
                    ),
                  ),
                  const SizedBox(
                    height: 30,
                  ),
                  Expanded(
                    child: ListView.builder(
                      itemCount: folderYear.length,
                      itemBuilder: (context, index) {
                       // final folder = folders![index];
                        return Container(
                          height: 80,
                          decoration: const BoxDecoration(
                            color: Colors.black,
                            borderRadius: BorderRadius.all(Radius.circular(20)),
                            boxShadow: [
                              BoxShadow(
                                  color: Color.fromARGB(75, 0, 0, 0),
                                  blurRadius: 4,
                                  spreadRadius: 0,
                                  offset: Offset(0, 4))
                            ],
                          ),
                          child: Center(
                            child: Padding(
                              padding: const EdgeInsets.all(5.0),
                              child: Text(
                                folderYear[index],
                                style: kCardTitleStyle,
                              ),
                            ),
                          ),
                        );
                      },
                    ),
                  )
                ],
              );
          }
        },
      ),
    );
  }
}

CodePudding user response:

A nullable variable is what you want, not a late variable. To check if something has been initialized, you should use a nullable variable, and your code is already set up to do so.

Just change

late Future<List<FirebaseFolder>> listResult;

to

Future<List<FirebaseFolder>>? listResult;

CodePudding user response:

The issue lies on listResult variable, this part is ok

class _DashBoardState extends State<DashBoard> {
  late List<String> folderYear = [];
  late Future<List<FirebaseFolder>> listResult;

But on getFolders()

Future<List<String>> getFolders() async {
    final storageRef = FirebaseStorage.instance.ref().child("front end");
    final listResult = await storageRef.listAll(); // here you are creatring local variable
    for (var prefix in listResult.prefixes) {
      folderYear.add(prefix.name);
    }
    return folderYear;
  }

It should be without final keyword

listResult = await storageRef.listAll();

Also, you can check about Flutter: Combine Multiple Future Tasks

  • Related