1

For instance we have a like button that when the user press it, it will call an http function somewhere in the cloud.

FlatButton(
  onPressed: () => callOnLikeFunction(),
);

What if the user pressed it multiple times (like and unlike over and over)? Then it will call the http function many times and can cause errors.

So I tried using

Future.delayed(Duration(seconds: 2)).then(() => 
callOnLikeFunction()
);

But this does not work because it will still fire as many times as pressed, just delayed.

So the question is how do we wait until the last press as the final decision of the user and ignore the other attempts?

Update: Defining the last tap: Suppose a user taps 3x with 500ms interval but the 3rd tap stands the test of time of 2seconds then the 3rd tap is considered the last tap

Zenko
  • 2,319
  • 2
  • 20
  • 46
  • Disable the button when after it's pressed and enable it again after `callOnLikeFunction`. – Christopher Moore Aug 26 '20 at 13:34
  • Thanks for the comment. But this is not a good user experience. We usually want the like button to be fast and responsive with splashy animation. So it must show this first to user but handle the background job under the hood. Same as if user post a comment but then edits it several times, we don’t want it to fire notifications multiple times either. – Zenko Aug 26 '20 at 13:39
  • You can just make the callback empty. Disabling it just means stopping the button press from doing anything, it doesn't mean making it disappear and change visual appearance necessarily. – Christopher Moore Aug 26 '20 at 13:40
  • Thanks. But sorry this does not answer my question. Because I don’t want to take the first tap but the last one then ignore the rest. – Zenko Aug 26 '20 at 13:44
  • It's unclear what you mean by "last tap". – Christopher Moore Aug 26 '20 at 13:49
  • Have you ever tap something multiple times? Well, some people do. Maybe they tap 3x or 4x. Unsure of what they want to do. We don’t want to hinder them from tapping. So we want to take the last tap (probably the one that waits for a few seconds before another tap comes if there is any). If they tap 3x in an interval of 500ms but the 3rd tap can wait for 2secs then the 3rd tap is the last one – Zenko Aug 26 '20 at 13:53
  • Why would you want to do the last tap. If you have an interval in mind it should be edited into the question. – Christopher Moore Aug 26 '20 at 13:55
  • Actually in the code example I did use the Future.delay example with 2 seconds duration. But anyway I added the words to explain better. Thanks for the heads up. – Zenko Aug 26 '20 at 13:57
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/220500/discussion-between-christopher-moore-and-zk-regen). – Christopher Moore Aug 26 '20 at 13:58
  • Have a look at my answer, it should give you the desired behaviour. – Herry Aug 26 '20 at 13:58

1 Answers1

1

You can use a boolean flag to decide what to do after the button press. After the first tap, the boolean switches and displays f.e. a Snackbar to indicate that the request is in progress.

requestIsInAction = false;

void buttonCallback() {
  if(!requestIsInAction) {
    requestIsInAction = true;
    // do the http stuff
  }
  else {
    // show error
  }
}

After the request finishes, set the flag to false again.

If you want to get the LAST tap, you can use a Timer, as it is suggested at that post. Basically, you decide for the amount of time that has to pass until the button press actually gets proccessed and set the timer for that duration. Each consequent button press can then reset the timer.

I would use the first solution though because the expected behaviour of a button is that it gets executed immediatly.

Herry
  • 365
  • 1
  • 14
  • Yes it will seems to get executed immediately. So we can change the UI to show to the user any behavior it supposed to show (i.e: color change or number incremented) but the backend only gets executed afterwards when its final (about 2 seconds). – Zenko Aug 26 '20 at 14:11