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

fix(animations): don't consume instructions for animateChild #44357

Conversation

dario-piotrowicz
Copy link
Contributor

@dario-piotrowicz dario-piotrowicz commented Dec 2, 2021

  • TODO: Fill body commit message if PR gets accepted

resolves #41483
resolves #30693

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

Issue Number: #41483 (also #30693)

Animations which include animateChild calls can fail to remove elements from the DOM as their players are ignored since they are unnecessary for the actual animations

What is the new behavior?

The aforementioned players are handled as skipped instead of ignoring them, making their callbacks/cleanups take place and removing the issue of not removing elements from the DOM

Does this PR introduce a breaking change?

  • Yes
  • No

@google-cla google-cla bot added the cla: yes label Dec 2, 2021
@dario-piotrowicz dario-piotrowicz changed the title fix(animations): dont consume instruction for animateChild fix(animations): don't consume instruction for animateChild Dec 2, 2021
@dario-piotrowicz dario-piotrowicz force-pushed the animations-no-consume-for-animateChild branch 2 times, most recently from 1dd744e to d0ebfe2 Compare December 2, 2021 23:44
@dario-piotrowicz
Copy link
Contributor Author

I just wanted to give some context for the reason for this change

See this stackblitz, if you try transitioning between One and Two you'll see that two elements are incorrectly being shown, you can also see that the main element gets the ng-animated-queued class which doesn't get removed:
Screenshot at 2021-12-03 11-21-20

The issue here is that animateChild removes the subInstruction for the player relative to the element making the call, effectively ignoring the player. This "ignores" the player as it is not necessary for the animation.

The real problem comes from the fact that the ignored player's callbacks do not get triggered, and that prevents the ng-animate-queued class from being removed (the class is added during trigger initialization), this also blocks the engine.processLeaveNode from being executed (as one of its players is ignored thus never completes):

function removeNodesAfterAnimationDone(
engine: TransitionAnimationEngine, element: any, players: AnimationPlayer[]) {
optimizeGroupPlayer(players).onDone(() => engine.processLeaveNode(element));
}


(
note: we don't accumulated dead elements as they are cleaned up during the next trigger initialization via the old player's destruction:

if (player.namespaceId == this.id && player.triggerName == triggerName && player.queued) {
player.destroy();
}
)



so I believe that the players should not be completely ignored as their callbacks are still necessary, with my changes thus we end up having more players on the animations' flush, but the extra ones are correctly marked as skipped:

const parentPlayers = this.playersByElement.get(parentWithAnimation);
if (parentPlayers && parentPlayers.length) {
player.parentPlayer = optimizeGroupPlayer(parentPlayers);
}
skippedPlayers.push(player);

skipped players still trigger their callbacks/cleanups without effecting the animation:

// the reason why we don't actually play the animation is
// because all that a skipped player is designed to do is to
// fire the start/done transition callback events
skippedPlayers.forEach(player => {
if (player.parentPlayer) {
player.syncPlayerEvents(player.parentPlayer);
} else {
player.destroy();
}
});

the only downside I can see here is that we end up with more players (even though skipped) in the animations' flush (as you can see from the updated unit tests), which I don't think makes much of a difference, and it does make sense because those players do exist and get skipped (from a user perspective, I don't think extra callbacks are called as those players are not associated with triggers, so there shouldn't be much of a difference there too)

@dario-piotrowicz dario-piotrowicz marked this pull request as ready for review December 3, 2021 12:16
@pullapprove pullapprove bot requested a review from alxhub December 3, 2021 12:16
@dario-piotrowicz dario-piotrowicz changed the title fix(animations): don't consume instruction for animateChild fix(animations): don't consume instructions for animateChild Dec 3, 2021
@dario-piotrowicz dario-piotrowicz force-pushed the animations-no-consume-for-animateChild branch from d0ebfe2 to a62a63e Compare December 3, 2021 12:40
@dario-piotrowicz
Copy link
Contributor Author

dario-piotrowicz commented Dec 3, 2021

I just noticed that this change also fixes #30693 which looks very broken in the current state 🙂
(I haven't looked too much into it, but there the elements never actually get cleaned up so they keep stacking up)

@dario-piotrowicz dario-piotrowicz force-pushed the animations-no-consume-for-animateChild branch from a62a63e to 71e8883 Compare December 3, 2021 19:31
@ngbot ngbot bot added this to the Backlog milestone Dec 6, 2021
Copy link
Contributor

@jessicajaniuk jessicajaniuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love that this fixes the two bugs. I think we just need some additional code comments and variable name updates to help clarify what's happening here.

@dario-piotrowicz
Copy link
Contributor Author

@jessicajaniuk thanks a lot for having a look at this!!!! 😍

I didn't add names to the players in the tests as they are sort of throw-away players (they are indeed skipped), but I do agree that it would be much nicer and clearer to give them more meaning and context, especially for someone reading the tests in the future

I'll fix it, thanks 🙂👍

TODO: Fill body commit if PR gets accepted

resolves angular#41483
resolves angular#30693
@dario-piotrowicz dario-piotrowicz force-pushed the animations-no-consume-for-animateChild branch 2 times, most recently from 66fedeb to b47f176 Compare December 10, 2021 23:14
@dario-piotrowicz
Copy link
Contributor Author

dario-piotrowicz commented Dec 10, 2021

@jessicajaniuk I've renamed the players and added comments before them explaining the acronyms, I hope this is ok (hopefully I am not being too verbose? 😓)

please have another look and tell me what you think 🙂

@dario-piotrowicz dario-piotrowicz force-pushed the animations-no-consume-for-animateChild branch from b47f176 to 5295a9f Compare December 10, 2021 23:31
expect(p2p.element.classList.contains('parent2')).toBeTruthy();
expect(p2cp.element.classList.contains('child')).toBeTruthy();
expect(p1p.element.classList.contains('parent1')).toBeTruthy();
expect(p1cp.element.classList.contains('child')).toBeTruthy();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why this last classList wasn't being checked 🤔 , I've added the check for good measures 🙂

Comment on lines +2197 to +2198
// - ( the player for the child animation executed by parent via query
// and animateChild is skipped entirely )
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this skipping/ignoring doesn't convince me, it may cause similar issues of missed cleanup calls 🤔 , I think that if/after this PR gets merged we should also look into this one and check if everything is ok 🤔

Copy link
Contributor

@jessicajaniuk jessicajaniuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🍪

Thanks for adding all the additional comments and clarifications here. I think it makes a big difference!

reviewed-for: fw-core, fw-animations

@jessicajaniuk jessicajaniuk removed the request for review from alxhub December 13, 2021 17:35
@jessicajaniuk jessicajaniuk added action: presubmit The PR is in need of a google3 presubmit action: merge The PR is ready for merge by the caretaker and removed action: presubmit The PR is in need of a google3 presubmit labels Dec 13, 2021
@jessicajaniuk jessicajaniuk added target: patch This PR is targeted for the next patch release and removed target: patch This PR is targeted for the next patch release labels Dec 13, 2021
@dario-piotrowicz
Copy link
Contributor Author

@jessicajaniuk sorry if it's a bit last minute 😅, I realized that it would be good to a unit test for this functionality, are you ok with us merging this PR now and me adding the unit test in a separate one? 🙂

@alxhub
Copy link
Member

alxhub commented Dec 14, 2021

This PR was merged into the repository by commit 38ddae1.

alxhub pushed a commit that referenced this pull request Dec 14, 2021
TODO: Fill body commit if PR gets accepted

resolves #41483
resolves #30693

PR Close #44357
@alxhub alxhub closed this in 38ddae1 Dec 14, 2021
@jessicajaniuk
Copy link
Contributor

@jessicajaniuk sorry if it's a bit last minute 😅, I realized that it would be good to a unit test for this functionality, are you ok with us merging this PR now and me adding the unit test in a separate one? 🙂

Yup! :)

dario-piotrowicz added a commit to dario-piotrowicz/angular that referenced this pull request Dec 15, 2021
add new unit test to make sure that leaving elements queried via
a parent queried via animateChild are correctly removed

this tests the fix introduced in PR angular#44357
dario-piotrowicz added a commit to dario-piotrowicz/angular that referenced this pull request Dec 15, 2021
add a new unit test to make sure that leaving elements queried via
a parent queried via animateChild are correctly removed

note: this tests the fix introduced in PR angular#44357
@dario-piotrowicz dario-piotrowicz deleted the animations-no-consume-for-animateChild branch December 15, 2021 23:20
dimakuba pushed a commit to dimakuba/angular that referenced this pull request Dec 28, 2021
dylhunn pushed a commit that referenced this pull request Jan 4, 2022
add a new unit test to make sure that leaving elements queried via
a parent queried via animateChild are correctly removed

note: this tests the fix introduced in PR #44357

PR Close #44489
dylhunn pushed a commit that referenced this pull request Jan 4, 2022
add a new unit test to make sure that leaving elements queried via
a parent queried via animateChild are correctly removed

note: this tests the fix introduced in PR #44357

PR Close #44489
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jan 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: animations cla: yes target: patch This PR is targeted for the next patch release
Projects
None yet
3 participants