Skip to content

Conversation

@ValentinVignal
Copy link
Contributor

Makes the data parameter of Draggable non-nullable.

Fixes #84816

If you had to change anything in the flutter/tests repo, include a link to the migration guide as per the breaking change policy.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: gestures flutter/packages/flutter/gestures repository. labels Aug 23, 2023
@ValentinVignal
Copy link
Contributor Author

@Piinks @chinmoy12c I created the PR to continue the discussion from #84816

I made Draggable.data non nullable and dummy fixed the lints for now. Should I do anything else or should I make the code support null?

Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a pretty big breaking change. Can we address the crash in DragTarget without changing data? It looks like it crashes because of a bad assumption it will not be null, can we check for that and change the code path where the crash occurs?

@ValentinVignal
Copy link
Contributor Author

ValentinVignal commented Aug 27, 2023

@Piinks, thank you for the review. I'm okay to change the code to not make data a required T but a T?. That would also induce some breaking changes though.

For example

void didDrop(_DragAvatar<Object> avatar) {
assert(_candidateAvatars.contains(avatar));
if (!mounted) {
return;
}
setState(() {
_candidateAvatars.remove(avatar);
});
widget.onAccept?.call(avatar.data! as T);
widget.onAcceptWithDetails?.call(DragTargetDetails<T>(data: avatar.data! as T, offset: avatar._lastOffset!));

would become something like

widget.onAccept?.call(avatar.data as T?); 
widget.onAcceptWithDetails?.call(DragTargetDetails<T?>(data: avatar.data as T?, offset: avatar._lastOffset!)); 

which will force me to change the signature of onAccept and onAcceptWithDetails.

Also, I might need to change DragTargetDetails to make its field data nullable and non-required.

Are you fine with it or do you see a better approach?

Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that we'd be able to land a change that makes it nullable, since all customers will need to change their function signature and then add handling for when it is null.

I am not sure I understand the issue this is trying to resolve, can you speak more to that? Maybe from there we can find a way to make a non breaking-change.

@ValentinVignal
Copy link
Contributor Author

ValentinVignal commented Sep 3, 2023

The issue is that Draggable<T> accepts a nullable/non-required T? data:

const Draggable({
super.key,
required this.child,
required this.feedback,
this.data,
this.axis,
this.childWhenDragging,
this.feedbackOffset = Offset.zero,
this.dragAnchorStrategy = childDragAnchorStrategy,
this.affinity,
this.maxSimultaneousDrags,
this.onDragStarted,
this.onDragUpdate,
this.onDraggableCanceled,
this.onDragEnd,
this.onDragCompleted,
this.ignoringFeedbackSemantics = true,
this.ignoringFeedbackPointer = true,
this.rootOverlay = false,
this.hitTestBehavior = HitTestBehavior.deferToChild,
this.allowedButtonsFilter,
}) : assert(maxSimultaneousDrags == null || maxSimultaneousDrags >= 0);
/// The data that will be dropped by this draggable.
final T? data;

So data can be null.

But DragTarget assumes data is never null and uses data! as T. For example in didDrop:

void didDrop(_DragAvatar<Object> avatar) {
assert(_candidateAvatars.contains(avatar));
if (!mounted) {
return;
}
setState(() {
_candidateAvatars.remove(avatar);
});
widget.onAccept?.call(avatar.data! as T);
widget.onAcceptWithDetails?.call(DragTargetDetails<T>(data: avatar.data! as T, offset: avatar._lastOffset!));
}

which throws a Null check operator used on a null value exception when data is actually null.


An alternative that could dodge breaking changes would be to do something like:

if (avatar.data != null) {
  widget.onAccept?.call(avatar.data! as T); 
  widget.onAcceptWithDetails?.call(DragTargetDetails<T>(data: avatar.data! as T, offset: avatar._lastOffset!));
}

It would not require us to change any function signature.

What do you think?

@Piinks
Copy link
Contributor

Piinks commented Sep 11, 2023

It would not require us to change any function signature.

That sounds reasonable to me. :) Thanks!

@ValentinVignal ValentinVignal force-pushed the fix-draggable-with-null-value branch from b09f983 to 753aeed Compare September 12, 2023 14:50
@ValentinVignal
Copy link
Contributor Author

@Piinks What do you think of fix: Don't call .data! when it is null ?

(Sorry I forced pushed, it was simpler than reverting my changes that were conflicting with main)

@goderbauer goderbauer requested a review from Piinks September 19, 2023 22:11
@ValentinVignal
Copy link
Contributor Author

@Piinks is there something else I should do on this PR or does it look good to you ?

@Piinks
Copy link
Contributor

Piinks commented Sep 25, 2023

is there something else I should do on this PR or does it look good to you ?

This is still marked as a draft, can you mark it ready for review? :)

…null-value

# Conflicts:
#	packages/flutter/test/widgets/draggable_test.dart
@ValentinVignal ValentinVignal marked this pull request as ready for review September 26, 2023 08:27
@ValentinVignal ValentinVignal force-pushed the fix-draggable-with-null-value branch from 8ad5dc8 to 2dc04d8 Compare September 26, 2023 08:29
@ValentinVignal
Copy link
Contributor Author

@Piinks Do you have any more feedback on this PR?

engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 3, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 3, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 3, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 3, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 3, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 3, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 3, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 3, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 4, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 4, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 4, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 4, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 5, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 5, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 6, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 6, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 6, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 6, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 6, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 6, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App f: gestures flutter/packages/flutter/gestures repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DragTarget crash if Draggable data field is not set, but data is not required.

4 participants