0

I have seen a few questions on this topic but have not found an answer. Given the following code I am trying to create a copy of the "kids" List from one instance to another. For Strings this works however for List it is only a reference and when I update the value of kids in the 2nd instance it also updates in the first. My code is below.

import 'package:flutter/material.dart';
import './screens/detail_screen.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  Person person1 = Person();
  List<Person> people = [];

  @override
  void initState() {
    super.initState();
    person1.firstName = 'Jack';
    person1.kids = [
      {'Karen': 'girl'},
      {'Bob': 'girl'}
    ];
    people.add(person1);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView.builder(
        itemCount: people.length,
        itemBuilder: (context, int index) {
          return ListTile(
            title: Text(
              '${people[index].firstName}',
            ),
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => DetailsScreen(people[index]),
                ),
              );
            },
          );
        },
      ),
    );
  }
}

class Person {
  String firstName;
  List kids;
}

class DetailsScreen extends StatefulWidget {
  final Person person;
  DetailsScreen(this.person);
  @override
  _DetailsScreenState createState() => _DetailsScreenState();
}

class _DetailsScreenState extends State<DetailsScreen> {
  static final TextEditingController _textController = TextEditingController();

  Person newPerson = Person();

  @override
  void initState() {
    super.initState();
    newPerson.firstName = widget.person.firstName;
    _textController.text = widget.person.firstName;
  }

  updateName(newName) {
    newPerson.firstName = newName;
// This is where I am trying to copy the value of "kids".
    newPerson.kids = List.from(widget.person.kids);
    newPerson.kids[1]['Bob'] = 'boy';
    print(newPerson);
    print(widget.person);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
            icon: Icon(
              Icons.close,
              color: Colors.white,
            ),
            onPressed: () {
              Navigator.pop(context);
            }),
        actions: <Widget>[
          IconButton(
              icon: Icon(
                Icons.check,
                color: Colors.white,
              ),
              onPressed: () {
                updateName(_textController.text);
              }),
        ],
      ),
      body: Center(
        child: TextField(
          controller: _textController,
        ),
      ),
    );
  }
}

Is there a way of doing this? If not what is best practice to achieve the same result? I have read this article but it refers to Strings and not Lists. How to clone (copy values) a complex object in Dart 2

1

2 Answers 2

2

Can you try this:

First import dart convert top of the page like this

import 'dart:convert';

Then update your updateName method with this one

updateName(newName) {
newPerson.firstName = newName;
List<dynamic> newPersonKids = jsonDecode(jsonEncode(widget.person.kids));
newPerson.kids = newPersonKids;
newPerson.kids[1]['Bob'] = 'boy';}
Sign up to request clarification or add additional context in comments.

1 Comment

Is this really the most efficient way of doing this?
-1

List.from(list) should work for creating a new instance of the list.

You can try this in the https://dartpad.dev/

final list = [0,1,2];
final newList = list;
print(newList);
list[0] = 55;
print(newList); //here, newList is changed because it is an instance of list

Result: [0,1,2] [55, 1, 2]

What you would expect:

final list = [0,1,2];
final newList = List.from(list);
print(newList);
list[0] = 55;
print(newList); //here, newList has no change because it is a new instance

Result: [0,1,2] [0,1,2]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.