Search code examples
flutterlisttileexpansion-tile

Flutter ExpansionTile ListTile Remove Element Bad state: No element


I want to show multiple ListTiles which represent elements out of a list in a ExpansionTile. The problem which I have is when I delete all the elements in that specific List then I get an error: Bad state: No element exception. How can I prevent this? I still want to keep the ExpansionTile itself.

enter image description here

class GroupsNew extends StatefulWidget {
const GroupsNew({super.key});

@override
State<GroupsNew> createState() => _GroupsNewState();
}

class _GroupsNewState extends State<GroupsNew> {
bool _customIcon = false;
List<String> test = ["string"];

@override
Widget build(BuildContext context) {
...
body: Padding(
    padding: const EdgeInsets.all(14.0),
    child: ExpansionTile(
    ...
    children: [
        ListTile(
        title: Text(test.first, style: TextStyle(fontSize: 20)),
          trailing: IconButton(
              onPressed: () {
                setState(() {
                  **test.remove(test.first);
                  if (test.length == 0) {
                    /// pls help :D ///**
                  }
                });
              },
             )
        ],
      onExpansionChanged: (bool expanded) {
        setState(() => _customIcon = expanded);
      },
    ),
  ),
);
}
}

Solution

  • To prevent the Bad state: No element exception when your list is empty, you can handle the case where the list has no elements. Specifically, after deleting all elements, you can check whether the list is empty and conditionally display a different widget (such as a placeholder or an empty state message) inside the ExpansionTile. Here's how you can modify your code:

       class GroupsNew extends StatefulWidget {
      const GroupsNew({super.key});
    
      @override
      State<GroupsNew> createState() => _GroupsNewState();
    }
    
    class _GroupsNewState extends State<GroupsNew> {
      bool _customIcon = false;
      List<String> test = ["string"];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('Groups')),
          body: Padding(
            padding: const EdgeInsets.all(14.0),
            child: ExpansionTile(
              title: Text('Expandable List'),
              trailing: Icon(_customIcon ? Icons.expand_less : Icons.expand_more),
              onExpansionChanged: (bool expanded) {
                setState(() => _customIcon = expanded);
              },
              children: test.isNotEmpty
                  ? test
                      .map((item) => ListTile(
                            title: Text(item, style: TextStyle(fontSize: 20)),
                            trailing: IconButton(
                              icon: Icon(Icons.delete),
                              onPressed: () {
                                setState(() {
                                  test.remove(item);
                                });
                              },
                            ),
                          ))
                      .toList()
                  : [
                      ListTile(
                        title: Text(
                          'No items available',
                          style: TextStyle(fontSize: 16, fontStyle: FontStyle.italic),
                        ),
                      ),
                    ],
            ),
          ),
        );
      }
    }