Skip to content

Make it easier to use chains of "await"s with animation controllers in widgets #5236

Closed

Description

@Hixie

Consider the following code:

Future<Null> fadeOutAndUpdateState() async {
   await fadeAnimationController.reverse();
   if (!mounted)
     return;
   await sizeAnimationController.reverse();
   if (!mounted)
     return;
   setState(() {
     dismissed = true;
   });
 }

...it would be nice if the "if (!mounted)" calls weren't needed, but right now they are.

One option would be to make controllers complete with an error when they are aborted (or maybe only when disposed?). That would abort the above function. Unfortunately then you'd have to have a function to wrap the call site of the above function to handle (and ignore) the resulting error in the future...

Activity

  1. self-assigned this
    on Aug 4, 2016
  2. Hixie commented on Aug 4, 2016

    @Hixie
    ContributorAuthor

    I have a branch (controller-error) where I tried this but it's going to require some study to determine if it's viable (a lot of our tests fail with it now because we uniformly ignore errors on these futures).

  3. added this to the milestone on Aug 4, 2016
  4. removed their assignment
    on Sep 26, 2016
  5. Hixie commented on Sep 26, 2016

    @Hixie
    ContributorAuthor

    Not gonna get to this soon.

  6. abarth commented on Sep 28, 2016

    @abarth
    Contributor

    What if awaited animation futures just never resolved if the animation gets disposed?

  7. abarth commented on Sep 28, 2016

    @abarth
    Contributor

    Looks like we already do that. If you dispose an AnimationController, you'll dispose the underlying ticker, which won't complete the future.

  8. Hixie commented on Sep 28, 2016

    @Hixie
    ContributorAuthor

    Yeah, but the problem with doing that is that any function that awaits an animation is now prone to hanging (from the perspective of the person writing the function).

  9. modified the milestones: , 2: Make Early Adopters happy on Dec 21, 2016
  10. self-assigned this
    on Jan 19, 2017
  11. removed their assignment
    on Mar 20, 2017
  12. Hixie commented on Apr 13, 2017

    @Hixie
    ContributorAuthor

    I'm toying with the idea of throwing an exception here that doesn't get reported as uncaught. Not quite sure how to do that... Anyway, doing that would let you use the pattern above while still being able to catch the case when the animation isn't going to terminate ever (so you can do cleanup, e.g. with try/finally). This might require support from the Dart SDK. It'd also require massive changes to our code base since so many places don't listen for errors. I need to look at this more closely.

    Alternatively, we could return an instance of a special Future subclass from which you can grab a second future which will throw when the ticker is stopped, so the call site gets to pick the behavior.

  13. Hixie commented on Apr 13, 2017

    @Hixie
    ContributorAuthor
    Future<Null> fadeOutAndUpdateState() async {
      try {
        await fadeAnimationController.reverse().orCancel;
        await sizeAnimationController.reverse().orCancel;
        setState(() {
          dismissed = true;
        });
      } on TickerCanceled {
        // the animation got aborted, probably because we were disposed
      }
    }
  14. added a commit that references this issue on May 17, 2018
  15. github-actions commented on Sep 5, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  16. locked as resolved and limited conversation to collaborators on Sep 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions