Skip to content

Commit

Permalink
docs: inject-destroy (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
eneajaho committed Sep 16, 2023
1 parent ca9606b commit cdbd2ad
Showing 1 changed file with 101 additions and 2 deletions.
103 changes: 101 additions & 2 deletions docs/src/content/docs/utilities/inject-destroy.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,105 @@ title: injectDestroy
description: ngxtension/inject-destroy
---

WIP
`injectDestroy` is a helper function that returns an observable that emits when the component is destroyed.

Link to [injectDestroy](https://github.com/nartc/ngxtension-platform/blob/main/libs/ngxtension/inject-destroy/src/inject-destroy.ts) source code.
It helps us to avoid memory leaks by unsubscribing from `Observable`s when the component is destroyed.

```ts
import { injectDestroy } from 'ngxtension/inject-destroy';
```

## Usage

If you are familiar with this pattern:

```ts
@Component({})
export class MyComponent implements OnInit, OnDestroy {
private dataService = inject(DataService);
private destroy$ = new Subject<void>();

ngOnInit() {
this.dataService.getData()
.pipe(takeUntil(this.destroy$))
.subscribe(...);
}

ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
```

You can replace it with `injectDestroy` and remove the boilerplate code:

```ts
@Component({})
export class MyComponent {
private dataService = inject(DataService);
private destroy$ = injectDestroy();

ngOnInit() {
this.dataService.getData()
.pipe(takeUntil(this.destroy$))
.subscribe(...);
}
}
```

As you can see, we don't need to implement `OnDestroy` anymore and we don't need to manually emit from the `Subject` when the component is destroyed.

## How it works

The helper functions injects the `DestroyRef` class from Angular, and on the `onDestroy` lifecycle hook, it emits from the `Subject` and completes it.

```ts
const destroyRef = inject(DestroyRef);
const subject$ = new ReplaySubject<void>(1);

destroyRef.onDestroy(() => {
subject$.next();
subject$.complete();
});

return subject$;
```

## Difference with `takeUntilDestroy` from Angular

Angular provides a `takeUntilDestroy` operator that does the same thing. But it requires us to pass the `DestroyRef` to the operator when we are not in an injection context.

```ts
@Component({})
export class MyComponent {
private dataService = inject(DataService);
private destroyRef = inject(DestroyRef);

ngOnInit() {
this.dataService.getData()
.pipe(takeUntilDestroy(this.destroyRef))
.subscribe(...);
}
}
```

While `injectDestroy` doesn't require us to pass the `DestroyRef` to the operator.

With `takeUntilDestroyed` we can also initialize the operator and use it later.

```ts
@Component({})
export class MyComponent {
private dataService = inject(DataService);
private takeUntilDestroyed$ = takeUntilDestroyed();

ngOnInit() {
this.dataService.getData()
.pipe(this.takeUntilDestroyed$)
.subscribe(...);
}
}
```

So, it's up to you to choose which one you prefer to use.

0 comments on commit cdbd2ad

Please sign in to comment.