Skip to content

Instantly share code, notes, and snippets.

@ltOgt
Created September 7, 2022 08:59
Show Gist options
  • Save ltOgt/664f98d3d2cb8f35aa992952b0e25713 to your computer and use it in GitHub Desktop.
Save ltOgt/664f98d3d2cb8f35aa992952b0e25713 to your computer and use it in GitHub Desktop.
CopyWith that works for "resetting" nullable fields
class Foo {
int bar;
int? baz;
Foo(this.bar, this.baz);
// The "normal" copyWith does not allow to "reset" nullable
// value to `null`.
// Passing `null` means "keep the value"
Foo copyWith({
int? bar,
int? baz,
}) => Foo(
bar ?? this.bar,
// This means we can never "reset" baz to `null`
baz ?? this.baz,
);
// Using callback for the copy means we get more options
// - dont pass the function (`null`) => keep the old value
// - pass the function (non `null`) => use the returned value
// - can be non-null
// - can be null
Foo copyWithFunc({
int Function(int barOld)? bar,
// null function => no change; null return from function => reset to null
int? Function(int? bazOld)? baz,
}) => Foo(
bar == null ? this.bar : bar(this.bar),
// can now be reset to null
baz == null ? this.baz : baz(this.baz),
);
}
void main() {
final foo = Foo(0,0);
// 1) change value
final one = foo.copyWithFunc(baz: (_) => 1);
print(one.baz);
// 2) keep value
final old = foo.copyWithFunc(baz: null);
print(old.baz);
// 3) reset to null
final nul = foo.copyWithFunc(baz: (_) => null);
print(nul.baz);
// For nested objects we could even do the following
// foo.copyWithFunc(nested: (old) => old.copyWithFunc(baz: (_) => newBaz));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment