Saqlain
Saqlain

Reputation: 330

Class final parameter is updating when I change local variable

I have a parameter for a stateful widget called 'Item' that has a list property called 'images'.

class ItemPage extends StatefulWidget {
  final PageMode mode;
  final Item? item;

  const ItemPage({
    Key? key,
    required this.mode,
    this.item,
  }) : super(key: key);

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

In my initstate function, i set the value of a local variable called 'images' to the value retrieved from the Item parameter as shown below.

  void initState() {
    // TODO: implement initState
    super.initState();

    switch (widget.mode) {
      case PageMode.create:
        purchaseDate = DateTime(
            DateTime.now().year, DateTime.now().month, DateTime.now().day);
        warrantyValid = DateTime(
            purchaseDate.year + 1, purchaseDate.month, purchaseDate.day);
        break;
      case PageMode.update:
        contName.text = widget.item!.productName;
        contCost.text = widget.item!.cost.toString();
        purchaseDate = widget.item!.purchaseDate;
        contPurchase.text = formattedDate(purchaseDate);
        warrantyValid = widget.item!.warrantyValid;
        contValid.text = formattedDate(warrantyValid);
        contSerial.text = widget.item!.serialNumber;
        contNotes.text = widget.item!.notes;
        contLink.text = widget.item!.link;
        images = widget.item!.images;

        break;
    }
  }

When i add an item to this local list- the original list also gets modified.

   setState(() {
      images.add({'path': file.path, 'type': 'local'});

    });

Below is a screenshot of the local variable right after an item has been added to the list.

enter image description here

Next is a screenshot of the original property from the final Item parameter in my class.

enter image description here

As you can see- both the lists have 2 items whereas the original final one should only have 1 item and the local one should have 2 items since I added one.

I can't seem to understand why the original keeps getting modified.

Upvotes: 1

Views: 255

Answers (1)

Tirth Patel
Tirth Patel

Reputation: 5736

This line images = widget.item!.images; assigns the reference of widget.item!.images to images variable. So if add is called on images, data would be added to widget.item!.images as well.

Here is a similar example to demonstrate the issue.

void main() {
  final a = [1, 2, 3];
  final b = a;
  b.add(4);
  print(a); // [1, 2, 3, 4]
  print(b); // [1, 2, 3, 4]
}

To solve this you can create a new list by calling toList(), addAll or using (...) spread operator:

void main() {
  final a = [1, 2, 3];
  final b = a.toList(); // or final b = [...a]; or final b = []; b.addAll(a);
  b.add(4);
  print(a); // [1, 2, 3]
  print(b); // [1, 2, 3, 4]
}

You could try running these snippets on dartpad.

Upvotes: 1

Related Questions