New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
copyWith may not work correctly when using null #906
Comments
To me, the behavior in 2.3.0+ is correct, and the previous behavior was a bug. Since there is no way for the code distinguish between a passed This is a known limitation. If you want to unset a field you have to manually create a new instance. Alternatively, if you find that too inconvenient, can always wrap the nullable value in something like an |
@tjarvstrand That is incorrect. Freezed is correctly able to determine if the parameter is passed or not. This is indeed a bug. |
Ah, TIL. Sorry about that! |
Any update on this? |
Nope. I'm on other things Otherwise it'll wait a bit |
I see. It using Freezed() as default |
Agree. The default value of properties when calling |
Any update on this? Is there any solution? |
@b4tchkn which version is currently used in your app? |
We are still using 2.2.1. |
How do I modify the To Reproduce test code listed in the Body to make it pass? |
any updates? I'm pretty sure it's a bug in freezed generator. the copyWith parameters should be wrapped in a Function like |
any updates? |
@tjarvstrand I'm a little lost here, since I assumed I just started using What is the correct approach when using I understand not passing the value as method argument when null is one way, but that would mean that I'd have to check for each property I might want to update if they should be part of return user.copyWith(
username: newUser.username // nullable
email: newUser.phoneNumber, // nullable
isPrivate: newUser.isPrivateProfile, // nullable
...
); would need to be written as: if (newUser.username != null) {
return user.copyWith(
username: newUser.username
);
}
if (newUser.email != null) {
return user.copyWith(
email: newUser.email
);
}
if (newUser.isPrivate != null) {
return user.copyWith(
isPrivate: newUser.isPrivate
);
}
... Doesn't seem right. What am I missing? |
Or, I assume tailing each nullable property by a return user.copyWith(
username: newUser.username ?? user.username // nullable
email: newUser.phoneNumber ?? user.phoneNumber, // nullable
isPrivate: newUser.isPrivateProfile ?? user.isPrivateProfile, // nullable
...
); |
I am using Modify generated freezed file: /// @nodoc
class _$SampleModelCopyWithImpl<T extends Object, $Res,
$Val extends SampleModel<T>> implements $SampleModelCopyWith<T, $Res> {
_$SampleModelCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
@pragma('vm:prefer-inline')
@override
$Res call({
Object? value = null,
}) {
return _then(_value.copyWith(
value: freezed == value // <-- NOTE: replace `null` with `freezed`
? _value.value
: value // ignore: cast_nullable_to_non_nullable
as T?,
) as $Val);
}
}
// ... and, // ...
/// @nodoc
class __$$SampleModelImplCopyWithImpl<T extends Object, $Res>
extends _$SampleModelCopyWithImpl<T, $Res, _$SampleModelImpl<T>>
implements _$$SampleModelImplCopyWith<T, $Res> {
__$$SampleModelImplCopyWithImpl(
_$SampleModelImpl<T> _value, $Res Function(_$SampleModelImpl<T>) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? value = null,
}) {
return _then(_$SampleModelImpl<T>(
value: freezed == value // <-- NOTE: replace `null` with `freezed`
? _value.value
: value // ignore: cast_nullable_to_non_nullable
as T?,
));
}
} Then in test: void main() {
test('sample model test', () {
printWrapped('hello');
const sampleModel = SampleModel(value: 9);
printWrapped(sampleModel);
expect(sampleModel, const SampleModel(value: 9));
final updatedSampleModel = sampleModel.copyWith(value: null);
printWrapped(updatedSampleModel);
expect(updatedSampleModel, const SampleModel<int>(value: null));
});
} |
Thanks for your info.
How was this done? |
Sorry, I'm just showing how the code is fixed. maybe we need to wait for the author to fix it based on the results of the manual patch I did earlier. |
Also note, this bug i test only appear when using generate freezed class with Generic (as described by @b4tchkn). Without generic, the generated code is works as expected (comparing with special |
Describe the bug
It was working fine when I was using 2.2.1, but when I update to 2.3.0 and higher it does not work correctly.
To Reproduce
Below is a simple model for checking behavior.
Here is the test code.
Test passes in 2.2.1, fails in 2.3.0 and higher.
The following differences were found in the code automatically generated by freezed.
Expected behavior
The above test code must pass.
The text was updated successfully, but these errors were encountered: