Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A dismissed Slidable widget is still part of the tree. #229

Closed
vytautas-pranskunas- opened this issue Jul 22, 2021 · 10 comments
Closed

A dismissed Slidable widget is still part of the tree. #229

vytautas-pranskunas- opened this issue Jul 22, 2021 · 10 comments

Comments

@vytautas-pranskunas-
Copy link

vytautas-pranskunas- commented Jul 22, 2021

I get this error if while widget remove animation is playing (or in other words while removing widget) i quickly click on it.
I think clicking on widget while animation is playing should be disabled.

version: 1.0.0-dev.6

I/flutter (24200): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (24200): The following assertion was thrown building SlidableDismissal(dirty, dependencies:
I/flutter (24200): [_EffectiveTickerMode], state: _SlidableDismissalState#f2a25(ticker inactive)):
I/flutter (24200): A dismissed Slidable widget is still part of the tree.
I/flutter (24200): Make sure to implement the onDismissed handle of the ActionPane and to immediately remove the
I/flutter (24200): Slidable widget from the application once that handler has fired.
I/flutter (24200):
I/flutter (24200): The relevant error-causing widget was:
I/flutter (24200):   Slidable-[<'pm_1JG3ziK89Xv1FBcHUCFOJsO2'>]
I/flutter (24200):
lib/…/payment_methods/payment_methods_page.dart:76
I/flutter (24200):
I/flutter (24200): When the exception was thrown, this was the stack:
@letsar
Copy link
Owner

letsar commented Jul 23, 2021

Did you removed the Slidable from the tree in the onDismissed? Can you share a sample code to reproduce it?

@vytautas-pranskunas-
Copy link
Author

It did not get removed yet because animation is still in progress... whil ein progress try to click on it

@vytautas-pranskunas-
Copy link
Author

sure

new Slidable(
      key: Key(notification.id),
      endActionPane: ActionPane(
        motion: const DrawerMotion(),
        extentRatio: 0.25,
        dismissible: DismissiblePane(
          onDismissed: () => _controller.onSwipeDetelete(notification.id, index),
          closeOnCancel: true,
        ),
        children: [
          SlidableAction(
            icon: Icons.delete,
            backgroundColor: CustomColors.imperialRed,
            onPressed: (context) {},
          ),
        ],
      ),
      child: notificationView,

@letsar
Copy link
Owner

letsar commented Jul 24, 2021

I tested it but I cannot reproduce. Can you send me a complete sample I would just have to run to reproduce the issue?

@vytautas-pranskunas-
Copy link
Author

I was able to track down this issue but not sure how to solve it.... DO not want to add custom logic to every slidable. Maybe you have an advice?
Issue is this:
onDismissed I am calling controller which is calling server to complete an action. If action is complete I am removing row from widget tree (from mobx store). This delay causes error.
I was able to reproduce this issue adding delay (in onSwipeDetelete method) before removing element

Future.delayed(Duration(seconds: 2), () => _store.removePaymentMethod(paymentMethodId));

@letsar
Copy link
Owner

letsar commented Jul 25, 2021

Ok I see now. What I would do would be to apply the principle of optimistic UI:
I would always remove the widget from the tree, and if there is an issue from the server, I would re-add the widget and show a toast to the user indicating them that an error occurred and the item was re-added.

@vytautas-pranskunas-
Copy link
Author

vytautas-pranskunas- commented Jul 25, 2021

Yes i know this technique but if i have 10 lists with removable row implementing such generic mechanics is costly. I wonder - maybe there is some other way to prevent this like library scope?

@letsar
Copy link
Owner

letsar commented Jul 25, 2021

In my opinion, it's not the scope of this library. If you have 10+ lists like that, you could create your own widget with you own abstractions to take into account this principle. You would have the same issue with the built-in Dismissible widget.

@vytautas-pranskunas-
Copy link
Author

vytautas-pranskunas- commented Jul 25, 2021

I see. Agree. closing.

Thanks

@mkbsugita
Copy link

it is closed issue.

My snippet.

        return Slidable(
          // Specify a key if the Slidable is dismissible.
          key: ValueKey('$index'),
          // The end action pane is the one at the right or the bottom side.
          endActionPane: ActionPane(
            extentRatio: 0.28,
            dismissible: DismissiblePane(
              onDismissed: () {
                // ERROR!
                _deleteCell(ref, myCell.id);
              },
            ),
            motion: const ScrollMotion(),
            children: [
              SlidableAction(
                onPressed: (context) {
                  // Not error. Why?? same method
                  _deleteCell(ref, myCell.id);
                },
                backgroundColor: const Color(0xFFFE4A49),
                foregroundColor: Colors.white,
                label: 'DELETE',
              ),
            ],

How is ValueKey?

And object worked?
like this

new Slidable(
    key: ValueKey(myCell),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants