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 Azzazy
  • 701
  • 1
  • 7
  • 16
  • 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 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
  • 520
  • 2
  • 7
  • 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 Azzazy Apr 09 '21 at 10:10