2

I have recently started learning Flutter and I am stuck at a point while dealing with Drag and Drop using Droppable and DragTarget. When I Drag my draggable element over DropTarget element, I am doing few validations in onWillAccept method. One of the conditions here requires me to confirm with user if they are willing to continue with their action before returning true and heading to onAccept method. For some reason, code execution does not wait for user's action to return.

This is how my DragTarget looks

DragTarget<Map>(
  builder: (context, listOne, listTwo) {
    return Container();
  },
  onWillAccept: (value) {
    if(condition1) {
      return true;
    } else if(condition2) {
      return true;
    } else {
      if(!condition3) {
        return true;
      } else {
        await _showConfirmation();
        return false;
      }
    }
  },
  onAccept: (value) {
    print(value);
  },
)

and _showConfirmation method looks something like this

Future<void> _showConfirmation() async {
  return showDialog<void>(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return AlertDialog(
        title: Text('Attention'),
        content: SingleChildScrollView(
          child: ListBody(
            children: <Widget>[
              Text('Some message")
            ],
          ),
        ),
        actions: <Widget>[
          FlatButton(
            child: Text('Accept'),
            onPressed: () {
              Navigator.of(context).pop();
              return true;
            },
          ),
          FlatButton(
            child: Text('Cancel'),
            onPressed: () {
              Navigator.of(context).pop();
              return false;
            },
          )
        ],
      );
    },
  );
}

Adding await does not help as onWillAccept is not async. Making it async did not help either.

_showConfirmation().then((result) {
  return result
})

Above code did not help either. In many cases, the dragged item is left hanging over DragTarget box.

Any help regarding this will appreciated, thank you.

vinit_1791
  • 162
  • 1
  • 2
  • 8
  • Are you sure that Dart supports `await`? I don't know the language but can find evidence that its Futures have `.then()` and `.catchError()` methods. – Roamer-1888 Mar 29 '20 at 21:16
  • Dart does support async/await https://dart.dev/codelabs/async-await. And I have also used .then() as per my last code block, but it did not produce expected results – vinit_1791 Mar 29 '20 at 21:35
  • OK. In that case the problem appears to be that the `onWillAccept` function is expected to return `true` (or presumably anything truthy) or `false` (or presumably anything falsy). After `await` on the previous line, it will return ``, which is truthy. I can't see how you can work round that other than submitting a pull request. – Roamer-1888 Mar 29 '20 at 21:51
  • You could try ignoring `condition3` in `onWillAccept`, ie `else { return true }` then branching on `condition3` in the `onAccept` handler. Not sure exactly how to do it in Dart but you may need also to branch depending on whether the value delivered to `onAccept` is a `` or not. May not be exactly what you want but may stimulate thought. – Roamer-1888 Mar 29 '20 at 22:10

1 Answers1

0

What happens here is that _showConfirmation() returns a Widget instead of a boolean - which what seems you're expecting from the snippet provided. The current setup lets false to be returned without waiting for the boolean value.

await _showConfirmation();
return false;

Instead of _showConfirmation() returning a Widget and proceeding to return false, you can wait for the value to be returned by using then().

Change _showConfirmation() to return a boolean

Future<bool> _showConfirmation() async {
  ...
}

then call await before returning.

return await _showConfirmation();
Omatt
  • 8,564
  • 2
  • 42
  • 144