dart-data-plugin icon indicating copy to clipboard operation
dart-data-plugin copied to clipboard

CopyWith doesn't change value if null is passed

Open radoslawsobies opened this issue 3 years ago • 4 comments

example MyObject.copyWith(field1: null) this will not set field1 to null value, old value remains

radoslawsobies avatar Oct 11 '21 18:10 radoslawsobies

The original idea was to have non-null values in the field. Do you have a suggestion for what the generated code might look like?

andrasferenczi avatar Jan 30 '22 18:01 andrasferenczi

There are a number of solutions discussed here.

The basic idea is provide some optional-like wrapper class that must be used for nullable properties. Alternatively, you could provide additional methods for each nullable field to set it to null.

So perhaps in the example in addition to the regular copy constructor you would have another method name copyWithField1Null().

dalewking avatar Sep 10 '22 15:09 dalewking

Or perhaps there are additional boolean parameters to the copyWith like field1Null for each nullable field that says to interpret null as truly null.

So for example:

class Foo {
  final String? name;
}

Would generate a copy constructor like this:

  Foo copyWith({
    String? name,
    bool nameNull = false,
  }) {
    return Foo(
      name: name ?? (nameNull ? null : this.name),
    );
  }

dalewking avatar Sep 10 '22 15:09 dalewking

A good solution for this is use ValueGetter like the sample bellow:


class ScheduleState {
  final ScheduleStatus status;
  final int? scheduleHour;
  final DateTime? scheduleDate;

  ScheduleState({required this.status, this.scheduleHour, this.scheduleDate});

  ScheduleState copyWith({
    ScheduleStatus? status,
    ValueGetter<int?>? scheduleHour,
    ValueGetter<DateTime?>? scheduleDate,
  }) {
    return ScheduleState(
      status: status ?? this.status,
      scheduleHour: scheduleHour != null ? scheduleHour() : this.scheduleHour,
      scheduleDate: scheduleDate != null ? scheduleDate() : this.scheduleDate,
    );
  }

And in controller to set values to nullable properties you must made a function call.

void selectHour(int hour) {
    if (hour == state.scheduleHour) {
      state = state.copyWith(scheduleHour: () => null);
    } else {
      state = state.copyWith(scheduleHour: () => hour);
    }
  }

ricardoemerson avatar Mar 29 '24 03:03 ricardoemerson