toastification icon indicating copy to clipboard operation
toastification copied to clipboard

Exception on close toastification manually [Probably only in flutter web]

Open codingwithsaeed opened this issue 1 year ago • 26 comments

Describe the bug This error occurs when I hit the close button.

Screenshots exception

Flutter information:

  • OS: [Windows]
  • Flutter Version: [3.13.6]
  • Toastification Version [1.0.1]

codingwithsaeed avatar Oct 17 '23 16:10 codingwithsaeed

I have the same issue on the web, it looks like it only happens when the progress bar option is set to true.

https://github.com/payam-zahedi/toastification/assets/2213079/75f5a572-3818-47a8-9c79-b8b0bec93034

callmephil avatar Oct 31 '23 20:10 callmephil

I couldn't find a solution for this.

Basically, I don't know how it is happening.

My guess is that it is related to Animated List and it's a bug of the flutter.

payam-zahedi avatar Nov 01 '23 04:11 payam-zahedi

I have the same issue on the web, it looks like it only happens when the progress bar option is set to true. Screen.Recording.2023-10-31.at.10.07.10.PM.mov

I could reproduce it even without progress bar

payam-zahedi avatar Nov 01 '23 04:11 payam-zahedi

This is still an issue on flutter web.

Flutter 3.19.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 7482962148 (5 days ago) • 2024-02-27 16:51:22 -0500
Engine • revision 04817c99c9
Tools • Dart 3.3.0 • DevTools 2.31.1

p4-k4 avatar Mar 03 '24 19:03 p4-k4

any update ?

Trung15010802 avatar Mar 13 '24 04:03 Trung15010802

any update ? Right after the toast is dismissed from screen, the error will show

Flutter 3.16.9 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 41456452f2 (7 weeks ago) • 2024-01-25 10:06:23 -0800
Engine • revision f40e976bed
Tools • Dart 3.2.6 • DevTools 2.28.5

andynvt avatar Mar 13 '24 04:03 andynvt

Wrap it with Future.delay: image

Trung15010802 avatar Mar 13 '24 04:03 Trung15010802

Wrap it with Future.delay: image

Does this work @Trung15010802 ?

andynvt avatar Mar 13 '24 04:03 andynvt

Wrap it with Future.delay: image

Does this work @Trung15010802 ?

It's work for me. I don't see any error

Trung15010802 avatar Mar 13 '24 04:03 Trung15010802

The problem is we don't have enough information to fix this

I'm not really sure what is the exact problem

payam-zahedi avatar Mar 13 '24 09:03 payam-zahedi

Wrap it with Future.delay: image

Does this work @Trung15010802 ?

It's work for me. I don't see any error

Thanks @Trung15010802. I've realized that addPostFrameCallback also works.

WidgetsBinding.instance.addPostFrameCallback(() => toastification.show());

andynvt avatar Mar 13 '24 09:03 andynvt

Turning off this code in the ToastificationManager class fixes the error but you lose the return animation.

// if (showRemoveAnimation) { // _listGlobalKey.currentState?.removeItem( // index, // (BuildContext context, Animation animation) { // return ToastHolderWidget( // item: removedItem, // animation: animation, // alignment: alignment, // transformerBuilder: _toastAnimationBuilder(removedItem), // ); // }, // duration: _createAnimationDuration(removedItem), // );

  //    if the [showRemoveAnimation] is false, we will remove the notification
  //   without showing the remove animation.
  // } else {
  //   _listGlobalKey.currentState?.removeItem(
  //     index,
  //     (BuildContext context, Animation<double> animation) {
  //       return const SizedBox.shrink();
  //     },
  //   );
  // } 

ErsinMandaci avatar Mar 26 '24 10:03 ErsinMandaci

Turning off this code in the ToastificationManager class fixes the error but you lose the return animation.

// if (showRemoveAnimation) { // _listGlobalKey.currentState?.removeItem( // index, // (BuildContext context, Animation animation) { // return ToastHolderWidget( // item: removedItem, // animation: animation, // alignment: alignment, // transformerBuilder: _toastAnimationBuilder(removedItem), // ); // }, // duration: _createAnimationDuration(removedItem), // );

  //    if the [showRemoveAnimation] is false, we will remove the notification
  //   without showing the remove animation.
  // } else {
  //   _listGlobalKey.currentState?.removeItem(
  //     index,
  //     (BuildContext context, Animation<double> animation) {
  //       return const SizedBox.shrink();
  //     },
  //   );
  // } 

This is not the solution

This not make sense to disable the return animation

we should find the exact problem

payam-zahedi avatar Mar 26 '24 15:03 payam-zahedi

Turning off this code in the ToastificationManager class fixes the error but you lose the return animation. // if (showRemoveAnimation) { // _listGlobalKey.currentState?.removeItem( // index, // (BuildContext context, Animation animation) { // return ToastHolderWidget( // item: removedItem, // animation: animation, // alignment: alignment, // transformerBuilder: _toastAnimationBuilder(removedItem), // ); // }, // duration: _createAnimationDuration(removedItem), // );

  //    if the [showRemoveAnimation] is false, we will remove the notification
  //   without showing the remove animation.
  // } else {
  //   _listGlobalKey.currentState?.removeItem(
  //     index,
  //     (BuildContext context, Animation<double> animation) {
  //       return const SizedBox.shrink();
  //     },
  //   );
  // } 

This is not the solution

This not make sense to disable the return animation

we should find the exact problem

Yes, I agree, I offered a suggestion as a temporary solution. Now as an advanced stage //duration: _createAnimationDuration(removedItem), in the comment line eliminated the error. However, I could not understand exactly what _createAnimationDuration does as a function.

if (showRemoveAnimation) {
    _listGlobalKey.currentState?.removeItem(
      index,
      (BuildContext context, Animation<double> animation) {
        return ToastHolderWidget(
          item: removedItem,
          animation: animation,
          alignment: alignment,
          transformerBuilder: _toastAnimationBuilder(removedItem),
        );
      },
      //duration: _createAnimationDuration(removedItem),
    );
  }

ErsinMandaci avatar Mar 27 '24 11:03 ErsinMandaci

I have the same issue on the web, it looks like it only happens when the progress bar option is set to true. Screen.Recording.2023-10-31.at.10.07.10.PM.mov

I could reproduce it even without progress bar

Same :(

KeithEyreDFM avatar Apr 22 '24 14:04 KeithEyreDFM

Wrap it with Future.delay: image

Does this work @Trung15010802 ?

It's work for me. I don't see any error

Thanks @Trung15010802. I've realized that addPostFrameCallback also works.

WidgetsBinding.instance.addPostFrameCallback(() => toastification.show());

Didn't work. Not did wrapping it in a Future(Duration.zero) :(

WidgetsBinding.instance.addPostFrameCallback((_) => toastification.show(
           context: context,
           type: ToastificationType.error,
           style: ToastificationStyle.flatColored,
           icon: const Icon(Icons.error_outline_rounded),
           title: const Text('No Items Available'),
           alignment: Alignment.topRight,
           autoCloseDuration: const Duration(seconds: 4),
           borderRadius: BorderRadius.circular(12.0),
           applyBlurEffect: true,
         ));

This also did not work. The crash still happens:

Future.delayed(Duration.zero, () {
  toastification.show(
    context: context,
    type: ToastificationType.error,
    style: ToastificationStyle.flatColored,
    icon: const Icon(Icons.error_outline_rounded),
    title: const Text('No Items Available'),
    alignment: Alignment.topRight,
    autoCloseDuration: const Duration(seconds: 4),
    borderRadius: BorderRadius.circular(12.0),
    applyBlurEffect: true,
  );
});

Error:

Error: AnimationController.dispose() called more than once. A given AnimationController cannot be disposed more than once. The following AnimationController object was disposed multiple times: AnimationController#d8f82(⏮ 0.000; paused; DISPOSED) dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 297:3 throw_ packages/flutter/src/animation/animation_controller.dart 823:9 <fn> packages/flutter/src/animation/animation_controller.dart 833:14 dispose packages/flutter/src/widgets/animated_scroll_view.dart 1198:55 <fn> dart-sdk/lib/async/zone.dart 1661:54 runUnary dart-sdk/lib/async/future_impl.dart 162:18 handleValue dart-sdk/lib/async/future_impl.dart 838:44 handleValueCallback dart-sdk/lib/async/future_impl.dart 867:13 _propagateToListeners dart-sdk/lib/async/future_impl.dart 643:5 [_completeWithValue] dart-sdk/lib/async/future_impl.dart 713:7 callback dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7 <fn>

KeithEyreDFM avatar Apr 22 '24 14:04 KeithEyreDFM

Wrap it with Future.delay: image

Does this work @Trung15010802 ?

It's work for me. I don't see any error

Thanks @Trung15010802. I've realized that addPostFrameCallback also works.

WidgetsBinding.instance.addPostFrameCallback(() => toastification.show());

Didn't work. Not did wrapping it in a Future(Duration.zero) :(

WidgetsBinding.instance.addPostFrameCallback((_) => toastification.show(
           context: context,
           type: ToastificationType.error,
           style: ToastificationStyle.flatColored,
           icon: const Icon(Icons.error_outline_rounded),
           title: const Text('No Items Available'),
           alignment: Alignment.topRight,
           autoCloseDuration: const Duration(seconds: 4),
           borderRadius: BorderRadius.circular(12.0),
           applyBlurEffect: true,
         ));

This also did not work. The crash still happens:

Future.delayed(Duration.zero, () {
  toastification.show(
    context: context,
    type: ToastificationType.error,
    style: ToastificationStyle.flatColored,
    icon: const Icon(Icons.error_outline_rounded),
    title: const Text('No Items Available'),
    alignment: Alignment.topRight,
    autoCloseDuration: const Duration(seconds: 4),
    borderRadius: BorderRadius.circular(12.0),
    applyBlurEffect: true,
  );
});

Error:

Error: AnimationController.dispose() called more than once. A given AnimationController cannot be disposed more than once. The following AnimationController object was disposed multiple times: AnimationController#d8f82(⏮ 0.000; paused; DISPOSED) dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 297:3 throw_ packages/flutter/src/animation/animation_controller.dart 823:9 <fn> packages/flutter/src/animation/animation_controller.dart 833:14 dispose packages/flutter/src/widgets/animated_scroll_view.dart 1198:55 <fn> dart-sdk/lib/async/zone.dart 1661:54 runUnary dart-sdk/lib/async/future_impl.dart 162:18 handleValue dart-sdk/lib/async/future_impl.dart 838:44 handleValueCallback dart-sdk/lib/async/future_impl.dart 867:13 _propagateToListeners dart-sdk/lib/async/future_impl.dart 643:5 [_completeWithValue] dart-sdk/lib/async/future_impl.dart 713:7 callback dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7 <fn>

Yes, it's still have error but not much like before. I have switched to another packge

Trung15010802 avatar Apr 22 '24 15:04 Trung15010802

@payam-zahedi The issue is in the implementation of AnimatedList, where dispose is called multiple times in different places. I fixied and now works without any exceptions. Until the fix is officially implemented, we can utilize the modified AnimatedList. Here's the PR #102

rebaz94 avatar Apr 30 '24 14:04 rebaz94

@rebaz94 If the issue is really in AnimatedList, and you know what causes the problem, it would be nice if you create a reproducible code without toastification package, and open the issue on flutter repo

komakur avatar May 21 '24 12:05 komakur

Wrap it with Future.delay: image

It work for me, find my implementation below :

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:toastification/toastification.dart';

void createSuccessToast(BuildContext context,
        {required String label,
        String? description,
        Duration? duration = const Duration(seconds: 5)}) =>
    Future.delayed(
        Duration.zero,
        () => toastification.show(
            context: context,
            title: Text(label),
            style: ToastificationStyle.flat,
            autoCloseDuration: duration,
            alignment: Alignment.topRight,
            description: description != null
                ? RichText(text: TextSpan(text: description))
                : null,
            boxShadow: const [
              BoxShadow(
                color: Color(0x07000000),
                blurRadius: 16,
                offset: Offset(0, 16),
                spreadRadius: 0,
              )
            ],
            type: ToastificationType.success));

LeadcodeDev avatar May 21 '24 23:05 LeadcodeDev

    showProgressBar: false, // this is probably what is fixing the issue

hongsw avatar Jun 29 '24 20:06 hongsw

@rebaz94 If the issue is really in AnimatedList, and you know what causes the problem, it would be nice if you create a reproducible code without toastification package, and open the issue on flutter repo

We already have one issue for this on flutter repo

payam-zahedi avatar Jul 01 '24 08:07 payam-zahedi

@rebaz94 If the issue is really in AnimatedList, and you know what causes the problem, it would be nice if you create a reproducible code without toastification package, and open the issue on flutter repo

Sorry, I'm unable to reproduce the bug without the toastification package.

rebaz94 avatar Jul 10 '24 09:07 rebaz94

@rebaz94 If the issue is really in AnimatedList, and you know what causes the problem, it would be nice if you create a reproducible code without toastification package, and open the issue on flutter repo

Sorry, I'm unable to reproduce the bug without the toastification package.

did you used state full widget?

payam-zahedi avatar Jul 10 '24 09:07 payam-zahedi

No, the content of toast is just a Text

rebaz94 avatar Jul 10 '24 10:07 rebaz94

the problem is when we are using the showProgress

in that situation we are using a state full widget for our toasts otherwise we are using stateless widgets

and the problem is happening only with statefull widget

payam-zahedi avatar Jul 10 '24 12:07 payam-zahedi

I see this error on auto close as well (but only once)

Error
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 296:3  throw_
errors.dart:296
packages/flutter/src/animation/animation_controller.dart 866:9               <fn>
animation_controller.dart:866
packages/flutter/src/animation/animation_controller.dart 876:14              dispose
animation_controller.dart:876
packages/flutter/src/widgets/animated_scroll_view.dart 1393:55               <fn>
animated_scroll_view.dart:1393
dart-sdk/lib/async/zone.dart 1661:54                                         runUnary
zone.dart:1661
dart-sdk/lib/async/future_impl.dart 163:18                                   handleValue
future_impl.dart:163
dart-sdk/lib/async/future_impl.dart 861:44                                   handleValueCallback
future_impl.dart:861
dart-sdk/lib/async/future_impl.dart 890:13                                   _propagateToListeners
future_impl.dart:890
dart-sdk/lib/async/future_impl.dart 666:5                                    [_completeWithValue]
future_impl.dart:666
dart-sdk/lib/async/future_impl.dart 736:7                                    callback
future_impl.dart:736
dart-sdk/lib/async/schedule_microtask.dart 40:11                             _microtaskLoop
schedule_microtask.dart:40
dart-sdk/lib/async/schedule_microtask.dart 49:5                              _startMicrotaskLoop
schedule_microtask.dart:49
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7           <fn>

rmahmadkhan avatar Aug 27 '24 11:08 rmahmadkhan

The issue is triggered by removing the overlay with the (not really) empty AnimatedList.

https://github.com/payam-zahedi/toastification/blob/423dae7520bf8a4ea10d48e90deeb96781ce1685/lib/src/core/toastification_manager.dart#L143-L153

When I disable the overlay removal or postpone it a little with (removedItem.animationDuration ?? config.animationDuration) + Durations.medium1, the exception no longer occurs.

Is it necessary to remove the overlay every time the AnimatedList is empty?

karelklic avatar Aug 30 '24 19:08 karelklic

@karelklic, you might be right.

It seems that the overlay could be moving off-screen just before the last toast animation completes.

Is it necessary to remove the overlay every time the AnimatedList is empty?

To address this, I think we need to remove the overlay, as it may display a hidden widget over the navigator widget.

Let's try increasing the duration and see if that resolves the issue.

Do you plan to open a PR for this? If so, I would appreciate it.

payam-zahedi avatar Sep 06 '24 09:09 payam-zahedi