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(core): Call onDestroy in production mode as well #40120

Closed
wants to merge 1 commit into from

Conversation

mhevery
Copy link
Contributor

@mhevery mhevery commented Dec 14, 2020

PR #39876 introduced an error where the onDestroy of ComponentRef would only get called if ngDevMode was set to true. This was because in dev mode we would freeze TCleanup to verify that no more static cleanup would get added to TCleanup array. This ensured that TCleanup was always present in dev mode. In production the TCleanup would get created only when needed. The resulting cleanup code was incorrectly indented and would only run if TCleanup was present causing this issue.

Fix #40105
## 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: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@google-cla google-cla bot added the cla: yes label Dec 14, 2020
@pullapprove pullapprove bot added the area: core Issues related to the framework runtime label Dec 14, 2020
@ngbot ngbot bot added this to the Backlog milestone Dec 14, 2020
@mhevery mhevery added action: merge The PR is ready for merge by the caretaker target: patch This PR is targeted for the next patch release labels Dec 14, 2020
Copy link
Contributor

@AndrewKushnir AndrewKushnir left a comment

Choose a reason for hiding this comment

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

Thanks for the fix Misko! 👍

I have a couple more proposals that we can look into to avoid similar issues:

  • rename getTViewCleanup and getLCleanup (to getOrCreateTViewCleanup and getOrCreateLViewCleanup respectively). This should highlight the fact that calling these methods might cause side effects.

  • in the storeCleanupWithContext function itself, call freeze only when tView.cleanup is not null, i.e.:

    // If context is null that this is instance specific callback. These callbacks can only be
    // inserted after template shared instances. For this reason in ngDevMode we freeze the TView.
    if (ngDevMode && tView.cleanup !== null) {
      Object.freeze(tView.cleanup);
    }

What do you think?

packages/core/test/acceptance/component_spec.ts Outdated Show resolved Hide resolved
@mhevery mhevery force-pushed the issue_40105 branch 2 times, most recently from d26bb53 to e3c0cb3 Compare December 14, 2020 23:36
@mhevery
Copy link
Contributor Author

mhevery commented Dec 14, 2020

  • rename getTViewCleanup and getLCleanup (to getOrCreateTViewCleanup and getOrCreateLViewCleanup respectively). This should highlight the fact that calling these methods might cause side effects.

DONE

  • in the storeCleanupWithContext function itself, call freeze only when tView.cleanup is not null, i.e.:

Unfortunately, I can't do that. null is initial value meaning we can still add to it. So there is no way to distinguish nothing added yet, vs nothing added and no more adding is allowed.

Copy link
Contributor

@AndrewKushnir AndrewKushnir left a comment

Choose a reason for hiding this comment

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

LGTM 👍 (just one minor comment)

packages/core/src/render3/instructions/shared.ts Outdated Show resolved Hide resolved
PR angular#39876 introduced an error where the `onDestroy` of `ComponentRef`
would only get called if `ngDevMode` was set to true. This was because
in dev mode we would freeze `TCleanup` to verify that no more
static cleanup would get added to `TCleanup` array. This ensured
that `TCleanup` was always present in dev mode. In production the
`TCleanup` would get created only when needed. The resulting cleanup
code was incorrectly indented and would only run if `TCleanup` was
present causing this issue.

Fix angular#40105
@mhevery
Copy link
Contributor Author

mhevery commented Dec 15, 2020

presubmit

josephperrott pushed a commit that referenced this pull request Dec 22, 2020
PR #39876 introduced an error where the `onDestroy` of `ComponentRef`
would only get called if `ngDevMode` was set to true. This was because
in dev mode we would freeze `TCleanup` to verify that no more
static cleanup would get added to `TCleanup` array. This ensured
that `TCleanup` was always present in dev mode. In production the
`TCleanup` would get created only when needed. The resulting cleanup
code was incorrectly indented and would only run if `TCleanup` was
present causing this issue.

Fix #40105

PR Close #40120
@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 22, 2021
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: core Issues related to the framework runtime cla: yes target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

onDestroy on ComponentRef isn't called in production mode
2 participants