Skip to content

docs: Add DestroyRef.destroyed and usage in lifecycle guide#64422

Closed
SkyZeroZx wants to merge 1 commit intoangular:mainfrom
SkyZeroZx:docs/update-destroyRef-destroyed
Closed

docs: Add DestroyRef.destroyed and usage in lifecycle guide#64422
SkyZeroZx wants to merge 1 commit intoangular:mainfrom
SkyZeroZx:docs/update-destroyRef-destroyed

Conversation

@SkyZeroZx
Copy link
Copy Markdown
Contributor

@SkyZeroZx SkyZeroZx commented Oct 15, 2025

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.dev 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

@pullapprove pullapprove bot requested a review from JeanMeche October 15, 2025 00:56
@angular-robot angular-robot bot added the area: docs Related to the documentation label Oct 15, 2025
@ngbot ngbot bot added this to the Backlog milestone Oct 15, 2025
Comment on lines +186 to +187
By checking `destroyRef.destroyed`, you can prevent executing code after the instance has been cleaned up, avoiding potential errors such as
[`ExpressionChangedAfterItHasBeenCheckedError`](errors/NG0100).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not that's correct. IIRC it was to address issues where NG0911 occured (view already destroyed), see #54527.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated, on the other hand we do not have an error guide for NG0911, would it be good to add one too?

Comment on lines +176 to +182
constructor() {
this.search.valueChanges.pipe(debounceTime(300)).subscribe(value => {
if (!this.destroyRef.destroyed) {
this.performSearch(value);
}
});
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not sure this example makes much sense. Users would use takeUntilDestroyed() instead.

I don't have an obivous example that comes to mind, maybe @atscott can chime in here.

Copy link
Copy Markdown
Contributor Author

@SkyZeroZx SkyZeroZx Oct 15, 2025

Choose a reason for hiding this comment

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

I was thinking a bit, what do you think of this example, the case of an animation or a background process like a heavy web worker could be a more suitable example?

@Component({ /* ... */ })
export class ProgressBar {
  private destroyRef = inject(DestroyRef);
  progress = 0;

  ngAfterViewInit() {
     const start = Math.floor(performance.now());

    const step = (now: number) => {
      // stop if component was destroyed
      if (this.destroyRef.destroyed) return;

      const elapsed = now - start;
      this.progress = Math.min(100, (elapsed / 1000) * 100);

      // schedule next frame while still alive
      if (this.progress < 100) requestAnimationFrame(step);
    };

    requestAnimationFrame(step);
  }

Or

@Component({ /* ... */ })
export class WorkerProcess {
  private readonly destroyRef = inject(DestroyRef);
  progress = 0;

  onProcess() {
    // Web Worker that performs heavy computation off the main thread
    const worker = new Worker(new URL('./heavy.worker', import.meta.url), { type: 'module' });

    worker.onmessage = (e: MessageEvent<{ progress: number }>) => {
      // stop if component was destroyed
      if (this.destroyRef.destroyed) return;
      this.progress = e.data.progress;  
    };

    // Kick off heavy task
    worker.postMessage({ cmd: 'start' /*, payload: bigData */ });
  }
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't know if there are really any good examples. When writing something from scratch or when the example is simple, there are often other ways of getting there without destroyRef.destroyed. The worker example is maybe fine-ish but arguably too complicated as an example still. To be honest, any example for this is probably beyond what the documentation should provide. There's no reason to have someone try to understand the purpose of the example code and try to figure out why/if DestroyRef.destroyed is necessary in that case.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1, let's remove the example.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

@SkyZeroZx SkyZeroZx force-pushed the docs/update-destroyRef-destroyed branch from 30161a3 to a15616e Compare October 15, 2025 01:10
@SkyZeroZx SkyZeroZx force-pushed the docs/update-destroyRef-destroyed branch from a15616e to bee3067 Compare October 18, 2025 15:50
@JeanMeche JeanMeche added action: merge The PR is ready for merge by the caretaker target: patch This PR is targeted for the next patch release labels Oct 20, 2025
@thePunderWoman
Copy link
Copy Markdown
Contributor

This PR was merged into the repository. The changes were merged into the following branches:

@angular-automatic-lock-bot
Copy link
Copy Markdown

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 Nov 21, 2025
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: docs Related to the documentation target: patch This PR is targeted for the next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants