0

A beginner kind of a question

as shown in below stateful widget,

I need to be able to modify in this modifiableListToPlayWith without modifying in inputList or this modifiableListToPlayWith

its a working code you can copy paste and test it,, this is actually surprising to me what's going wrong here?

    import 'package:flutter/material.dart';

/// lets assume the input list is defined outside as ['value1','value2','value3']
class StateTest extends StatefulWidget {
  final List<String> inputList;

  StateTest({
    @required this.inputList,
});

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

class _StateTestState extends State<StateTest> {
  List<String> originalImmutableList = new List();
  List<String> modifiableListToPlayWith = new List();

  @override
  void initState() {
    modifiableListToPlayWith = widget.inputList;
    originalImmutableList = widget.inputList;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        color: Colors.blue,
        child: Column(
          children: <Widget>[

            GestureDetector(
              onTap: (){
                setState(() {
                  // it should add new values only to this list
                  modifiableListToPlayWith.add('value ${modifiableListToPlayWith.length + 1}');
                });
              },
              child: Container(
                width: 200,
                height: 50,
                color: Colors.amber,
                margin: EdgeInsets.only(top: 40),
                alignment: Alignment.center,
                child: Text(
                  'Add',
                  style: TextStyle(fontSize: 20),
                ),
              ),
            ),

            ...List.generate(modifiableListToPlayWith.length, (index){
              return
                Text(modifiableListToPlayWith[index]);
            }),

            Expanded(child: Container(),),

            Container(
              width: MediaQuery.of(context).size.width,
              child: Column(
                children: <Widget>[

                  Container(
                    width: MediaQuery.of(context).size.width,
                    height: 40,
                    color: Colors.deepOrangeAccent,
                    child: Text('modifiableListToPlayWith.length = ${modifiableListToPlayWith.length}'),
                  ),

                  Container(
                    width: MediaQuery.of(context).size.width,
                    height: 40,
                    color: Colors.redAccent,
                    child: Text('originalImmutableList.length = ${originalImmutableList.length}'),
                  ),

                  Container(
                    width: MediaQuery.of(context).size.width,
                    height: 40,
                    color: Colors.orangeAccent,
                    child: Text('widget.inputList.length = ${widget.inputList.length}'),
                  ),

                ],
              ),
            ),

          ],
        ),
      ),
    );
  }
}

see how the three lists in the picture below are copies of each other while in setstate method we are only adding the new value to this 'modifiableListToPlayWith'

Rageh El Azzazy
  • 571
  • 1
  • 5
  • 14
  • You're not making separate copies of the List; you're making multiple references to it. Here's a relevant thread: https://stackoverflow.com/questions/13107906/how-can-i-clone-an-object-deep-copy-in-dart – Don R Apr 08 '21 at 21:41
  • ohhhh this makes sense now,, you can only make copies of basic variables like strings and integers, simple maps but not a list nor a class of variables and I have to create a method to do that on the level of each variable in a class or in the list,, will try thanks alot – Rageh El Azzazy Apr 08 '21 at 22:43
  • In dart, everything is object. So, if you copy a list to another list without call toList(). It takes as reference type. So it will reflect the changes to the all the reference object. Use `modifiableListToPlayWith = widget.inputList.toList()`. – Ashok Kuvaraja Apr 09 '21 at 02:04

1 Answers1

1

Per Don's comment you are assigning the reference to the list, you are not copying it. Dart has a simple way to create a copy: Instead of modifiableListToPlayWith = widget.inputList; use modifiableListToPlayWith = List.from(widget.inputList); which will create the copy you are looking for.

Bram
  • 317
  • 1
  • 6
  • and for more complex objects like a class User(); with multiple parameters and other classes inside it,, I had to create set of methods to perform the cloning tasks for each single primary parameter and return a new clone object of the original complex User(); object thanks all for your prompt replies – Rageh El Azzazy Apr 09 '21 at 10:10