Home > Enterprise >  How to set New Variable value from Old Variable value but with Object / Model Data
How to set New Variable value from Old Variable value but with Object / Model Data

Time:12-06

How to set New Variable value from Old Variable value, if New Variable value changed the Old Variable not follow the changes. with Condition of type Data is Object? I actually asked about this problem here

But the problem I found confused me. Just look for the example code:

void main() {
  final Data mainData = Data(
    data: [
      Group(
        id: 1,
        groupName: 'Assault Riffle',
        weaponItems: [
          Weapon(id: 1, name: 'Ak47'),
          Weapon(id: 2, name: 'M4'),
        ],
      ),
      Group(
        id: 2,
        groupName: 'SMG',
        weaponItems: [
          Weapon(id: 3, name: 'MP5'),
          Weapon(id: 4, name: 'Dual UZI'),
        ],
      ),
    ],
  );

  final Data newData = Data(data: mainData.data); // create new Instance
  print('before mainData: ${mainData.data?[0].weaponItems?[0].name}'); // mainData: Ak47
      
  newData.data?[0].weaponItems?[0].name = 'SCAR';

  print('newData: ${newData.data?[0].weaponItems?[0].name}'); // newData: SCAR
  print('after mainData: ${mainData.data?[0].weaponItems?[0].name}'); // mainData: Scar (should Ak47)
}

As you can see the newData that I changed made the data in mainData change even though I had created a new instance.

The model data class:

class Data {
  List<Group>? data;

  Data({this.data});
}

class Group {
  int? id;
  List<Weapon>? weaponItems;
  String? groupName;

  Group({
    this.id,
    this.weaponItems,
    this.groupName,
  });
}

class Weapon {
  int? id;
  String? name;

  Weapon({this.id, this.name});
}

How to solve this problem?

CodePudding user response:

You need to make a deep copy of the structure to do what you want to do. This is a way to do it:

final Data newData = Data(
    data: mainData.data
        ?.map((group) => Group(
            id: group.id,
            weaponItems: group.weaponItems
                ?.map((weapon) => Weapon(id: weapon.id, name: weapon.name))
                .toList(),
            groupName: group.groupName))
        .toList());

CodePudding user response:

Your problem is how you access the data. When you copy an array in dart you don't copy it but you actually copy the pointer to the array. Copy your array elements 1 by 1 and you won't have this problem anymore.

Replace your :

final Data newData = Data(data: mainData.data); // create new Instance

by

final Data newData = Data();
for(Group group in mainData.data){ 
 newData.data.add(group); 
}

CodePudding user response:

i created adjustment to your modelling and create custom function like copyWith and replaceWeapon, it will come handy if you need to change something.

the result :

final Data mainData = Data(
    data: [
      Group(
        id: 1,
        groupName: 'Assault Riffle',
        weaponItems: [
          Weapon(id: 1, name: 'Ak47'),
          Weapon(id: 2, name: 'M4'),
        ],
      ),
      Group(
        id: 2,
        groupName: 'SMG',
        weaponItems: [
          Weapon(id: 3, name: 'MP5'),
          Weapon(id: 4, name: 'Dual UZI'),
        ],
      ),
    ],
  );

  final Data newData = mainData.copyAndReplaceWeaponAt(
      indexGroup: 0, indexWeapon: 0, newWeapon: Weapon(name: 'SCAR'));

  print('newData: ${newData.data[0].weaponItems[0].name}'); // newData: SCAR
  print('after mainData: ${mainData.data[0].weaponItems[0].name}'); //----> AK47

modelling :

class Data {
  final List<Group> data;
  Data({List<Group>? data}) : data = data ?? [];

  Data copyAndReplaceWeaponAt(
      {required int indexGroup,
      required int indexWeapon,
      required Weapon newWeapon}) {
    return Data(
        data: List.generate(data.length, (index) {
      if (index == indexGroup) {
        List<Weapon> weapons =
            List.generate(data[indexGroup].weaponItems.length, (index) {
          if (index == indexWeapon) {
            return data[indexGroup]
                .weaponItems[indexWeapon]
                .copyWith(id: newWeapon.id, name: newWeapon.name);
          }
          return data[indexGroup].weaponItems[index];
        });
        return data[index].copyWith(weaponItems: weapons);
      }
      return data[index];
    }));
  }
}

class Group {
  final int? id;
  final List<Weapon> weaponItems;
  final String? groupName;

  Group({this.id, this.groupName, List<Weapon>? weaponItems})
      : weaponItems = weaponItems ?? [];

  Group copyWith({
    int? id,
    List<Weapon>? weaponItems,
    String? groupName,
  }) {
    return Group(
        id: id ?? this.id,
        weaponItems: weaponItems ?? this.weaponItems,
        groupName: groupName ?? this.groupName);
  }
}

class Weapon {
  final int? id;
  final String? name;

  Weapon({this.id, this.name});

  Weapon copyWith({
    int? id,
    String? name,
  }) {
    return Weapon(id: id ?? this.id, name: name ?? this.name);
  }
}
  • Related