Creating a List of Objects Via Another Object and ListView.builder in Flutter

934

Ok so stupid mistake on my part, the reason the name parameter wasn't being passed on instantiation of Mesocycle object is because in the Mesocycle constructor, i didn't used 'required this.name', i used 'required name'

class Mesocycle {
  String name = 'none';
  var duration;
  Mesocycle({required this.name, required this.duration});
}
Share:
934
XavierRenegadeAngel
Author by

XavierRenegadeAngel

Updated on January 04, 2023

Comments

  • XavierRenegadeAngel
    XavierRenegadeAngel over 1 year

    I'm trying to create a list of objects via a method used by another object in flutter.

    When the user presses the button 'add new block', a bottomsheet comes up and the program successfully creates the new block by adding it to list of blocks with createBlock() and it is displayed in the parent listview.

    Inside of that listview is another listview, and a button "add new mesocycle'. same thing, bottomsheet comes up, except when i try to create a new mesocycle and name it via block[index].mesocycles[index].add(Mesocycle(name: widget.textController.text) and add it to the child listview, i get an error saying that the blocks[index].mesocycles[index].name is null.

    not sure why this is happening or how to fix.

    please let me know what solutions come to mind or if you can see what im doing wrong here.

    Here are the class definitions of the two objects:

    class Mesocycle {
      var name;
      var duration;
      Mesocycle({required name, required duration});
    }
    
    class Block {
      String name;
      List<Mesocycle> mesocycles = [];
    
      Block({required this.name});
    
      void createMesocycle({required String name, required duration}) {
        mesocycles.add(Mesocycle(name: name, duration: duration));
        print('number of mesocycles in this block: ' + '${mesocycles.length}');
      }
    }
    

    Ok, and here is the main statefulwidget where all of the rendering takes place:

    class MyHomePage extends StatefulWidget {
      MyHomePage({Key? key, required this.title}) : super(key: key);
    
      
      final String title;
      final List<Block> blocks = [];
      final List<String> years = ['2022'];
      final textController = TextEditingController();
      final textController1 = TextEditingController();
      void createBlock({required String name}) {
        blocks.add(Block(name: name));
      }
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text(widget.title)),
          body: Column(
            children: [
              widget.blocks.length > 0
                  ? Expanded(
                      child: ListView.builder(
                        itemCount: widget.blocks.length,
                        itemBuilder: (context, index) {
                          return ExpansionTile(
                            title: Center(child: Text(widget.blocks[index].name)),
                            children: [
                              widget.blocks[index].mesocycles.length > 0
                                  ? ListView.builder(
                                      shrinkWrap: true,
                                      itemCount:
                                          widget.blocks[index].mesocycles.length,
                                      itemBuilder: (context, index) {
                                        return Container(
                                            child: Text(widget.blocks[index]
                                                .mesocycles[index].name));
                                      })
                                  : Container(child: Text('empty')),
                              Container(
                                  child: TextButton(
                                child: Text('Add New Mesocycle'),
                                onPressed: () {
                                  showModalBottomSheet(
                                      context: context,
                                      builder: (BuildContext context) {
                                        return Container(
                                            height: 200,
                                            color: Colors.grey[800],
                                            child: Column(
                                              children: [
                                                Container(
                                                    child: TextField(
                                                        decoration: InputDecoration(
                                                            hintText:
                                                                'Mesocycle Name',
                                                            border:
                                                                InputBorder.none),
                                                        controller:
                                                            widget.textController)),
                                                ElevatedButton(
                                                  child: Text('Create Mesocycle'),
                                                    onPressed: () {
                                                      setState(() {
                                                        widget.blocks[index]
                                                            .createMesocycle(
                                                                name: widget
                                                                    .textController
                                                                    .text,
                                                                duration: 8);
                                                        widget.textController
                                                            .clear();
                                                        Navigator.pop(context);
                                                      });
                                                    },
                                                    )
                                              ],
                                            ));
                                      });
                                },
                              )),
                            ],
                          );
                        },
                      ),
                    )
                  : Center(
                      child: Padding(
                      padding: const EdgeInsets.all(20.0),
                      child: Text('No Data'),
                    )),
              Container(
                child: TextButton(
                  child: Text('Add New Block'),
                  onPressed: () {
                    showModalBottomSheet(
                        context: context,
                        builder: (BuildContext context) {
                          return Container(
                              height: 200,
                              color: Colors.grey[800],
                              child: Column(
                                children: [
                                  Container(
                                      child: TextField(
                                          decoration: InputDecoration(
                                              hintText: 'Block Name',
                                              border: InputBorder.none),
                                          controller: widget.textController)),
                                  ElevatedButton(
                                      onPressed: () {
                                        setState(() {
                                          widget.createBlock(
                                              name: widget.textController.text);
                                          widget.textController.clear();
                                          Navigator.pop(context);
                                        });
                                      },
                                      child: Text('Create'))
                                ],
                              ));
                        });
                  },
                ),
              ),
            ],
          ),
        );
      }
    }
    

    when i print blocks[index].mesocycles[index].length it confirms that objects are being added to the list, but again, when i try to return their .name property it is null.

    this makes me think that something is going wrong with the parameter actually being passed properly during instantiation, either something wrong with the index or data type, but i can't see what's wrong with what i have