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);
}
}