Pass List to another Class in Flutter

Viewed 11934

I have a list 'names' of strings in a NameViewList and trying to pass its values to another class Basic().

I tried this approach but it gives me an error: error: 'names' is final and was given a value when it was declared, so it can't be set to a new value. (final_initialized_in_declaration_and_constructor at [flutterspinningwheel] lib/nameviewlist.dart:5)

I used this way to pass variable and it was working but when I pass list it does not work

     class NameViewList extends StatefulWidget {
  NameViewList({Key key, this.names});
  final List<String> names = <String>[];

  @override
  _NameViewListState createState() => _NameViewListState();
}

class _NameViewListState extends State<NameViewList> {


  TextEditingController nameController = TextEditingController();

   createDialog(BuildContext context){
    return showDialog(context: context, builder: (context) {
      return AlertDialog(
        title: Text('Insert Name'),
        content: TextField(
          controller: nameController,
          decoration: InputDecoration(
            border: OutlineInputBorder(),
            labelText: 'Contact Name',
          ),
        ),
        actions: [
          MaterialButton(
            child: Text('Submit'),
            onPressed: (){
              addItemToList();
              Navigator.of(context).pop();
            },
          )
        ],
      );
    });
  }

  void addItemToList(){
    setState(() {
      widget.names.insert(0, nameController.text);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Settings'),
        centerTitle: true,
      ),
      body: Column(
        children: [
          IconButton(
            icon: Icon(Icons.queue, color: Colors.green,),
            onPressed: (){createDialog(context);},
          ),
          Padding(
            padding: EdgeInsets.all(20),
            child: TextField(
              controller: nameController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Contact Name',
              ),
            ),
          ),
          Row(
            children: [
              RaisedButton(
                child: Text('Clear'),
                onPressed: () {
                  setState(() {
                    widget.names.clear();

                  });
                },
              ),
              RaisedButton(
                child: Text('Submit'),
                onPressed: () {
                  Navigator.of(context).push(MaterialPageRoute(builder: (context)=> Basic(names: names)));
                },
              ),
            ],
          ),
2 Answers

Change this lines:

  NameViewList({Key key, this.names});
  final List<String> names = <String>[];

To:

  NameViewList({List<String> names}) : this.names = names ?? [];
  final List<String> names;

Your problem is that you are setting a final variable with a value twice. First you set it to a empty list of strings. And then you are setting it again if the optional parameter (if no optional parameter the value are set to null).

Instead, my solution changes it so we are only setting the names variable once by first asking if the optional parameter is null (not set) and if that is the case, we set the value to the empty list. Otherwise, we use the optional parameter.

You're not able to modify a variable if declared with the final constructor. So, what you can do to solve your problem is create another variable and attributes the value of the final to it. The problem may be solved with this:

class NameViewList extends StatefulWidget {
  final List<String> names;
  NameViewList({Key key, this.names});

  @override
  _NameViewListState createState() => _NameViewListState();
}

class _NameViewListState extends State<NameViewList> {
  TextEditingController nameController = TextEditingController();
  List<String> names = <String>[];

  createDialog(BuildContext context) {
    return showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text('Insert Name'),
            content: TextField(
              controller: nameController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Contact Name',
              ),
            ),
            actions: [
              MaterialButton(
                child: Text('Submit'),
                onPressed: () {
                  addItemToList();
                  Navigator.of(context).pop();
                },
              )
            ],
          );
        });
  }

  void addItemToList() {
    setState(() {
      names.insert(0, nameController.text);
    });
  }

  @override
  void initState() {
    super.initState();
    names = widget.names;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Settings'),
        centerTitle: true,
      ),
      body: Column(
        children: [
          IconButton(
            icon: Icon(
              Icons.queue,
              color: Colors.green,
            ),
            onPressed: () {
              createDialog(context);
            },
          ),
          Padding(
            padding: EdgeInsets.all(20),
            child: TextField(
              controller: nameController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Contact Name',
              ),
            ),
          ),
          Row(
            children: [
              RaisedButton(
                child: Text('Clear'),
                onPressed: () {
                  setState(() {
                    names.clear();
                  });
                },
              ),
              RaisedButton(
                child: Text('Submit'),
                onPressed: () {
                  Navigator.of(context).push(MaterialPageRoute(
                      builder: (context) => Basic(names: names)));
                },
              ),
            ],
          )
        ],
      ),
    );
  }
}
Related