← → or space · progress saves for Continue on the roadmap
Goal
Create a new instance like the old one but with a few fields changed, without mutating the original.
Step 1 - Simple copyWith
class User {
final String name;
final int age;
User({required this.name, required this.age});
User copyWith({String? name, int? age}) {
return User(
name: name ?? this.name,
age: age ?? this.age,
);
}
}
void main() {
User a = User(name: 'Asha', age: 20);
User b = a.copyWith(age: 21);
print('${a.name} ${a.age}');
print('${b.name} ${b.age}');
}??keeps the old value when the argument is omitted (nullmeans “no change”).
Step 2 - Nullable fields need a sentinel (later pattern)
- If
String? biocan benullon purpose,copyWith({String? bio})cannot distinguish “leave bio alone” from “set bio to null” with only??. - For this level, prefer non-nullable fields or accept the limitation until you learn wrapper types or
Object?sentinels.
Step 3 - When to use
- UI state, value models, configs: copy instead of mutating shared instances.
- Large graphs: consider where copying should be shallow vs deep (manual
copyWithis usually shallow).
Good habit
- After
copyWith, assert or test that the old instance still has old values (see build guides).
Practice tasks
- Add
copyWithto aProductwithsku,name,price(all non-nullableString/double). - Create
u2 = u1.copyWith()with no args; confirmu1andu2are equal in value but not the same object (identicalvs==once you implement equality).