Skip to content

Instantly share code, notes, and snippets.

@AustinMatherne
Last active November 1, 2019 11:11
Show Gist options
  • Save AustinMatherne/fd14e2813f8d9a43f618f0db014e4418 to your computer and use it in GitHub Desktop.
Save AustinMatherne/fd14e2813f8d9a43f618f0db014e4418 to your computer and use it in GitHub Desktop.
Angular `ObservableLifecycles` Component Base Class
import {
OnChanges,
OnInit,
DoCheck,
OnDestroy,
AfterContentInit,
AfterContentChecked,
AfterViewInit,
AfterViewChecked,
SimpleChanges
} from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { Subject } from 'rxjs/Subject';
import { takeUntil, filter, map } from 'rxjs/operators';
export interface Lifecycles<T> {
ngOnChanges: <R extends keyof T>(key: R) => Observable<T[R]>;
ngOnInit: Observable<void>;
ngDoCheck: Observable<void>;
ngOnDestroy: Observable<void>;
ngAfterContentInit: Observable<void>;
ngAfterContentChecked: Observable<void>;
ngAfterViewInit: Observable<void>;
ngAfterViewChecked: Observable<void>;
}
const observeLifecycles = <T extends ObservableLifecycles>(
component: T
): Lifecycles<T> => {
const lifecycles = {
ngOnChanges: new Subject<SimpleChanges>(),
ngOnInit: new ReplaySubject<void>(),
ngDoCheck: new Subject<void>(),
ngOnDestroy: new ReplaySubject<void>(),
ngAfterContentInit: new ReplaySubject<void>(),
ngAfterContentChecked: new Subject<void>(),
ngAfterViewInit: new ReplaySubject<void>(),
ngAfterViewChecked: new Subject<void>()
};
const originalLifecycleHooks = {
ngOnChanges: component.ngOnChanges,
ngOnInit: component.ngOnInit,
ngDoCheck: component.ngDoCheck,
ngOnDestroy: component.ngOnDestroy,
ngAfterContentInit: component.ngAfterContentInit,
ngAfterContentChecked: component.ngAfterContentChecked,
ngAfterViewInit: component.ngAfterViewInit,
ngAfterViewChecked: component.ngAfterViewChecked
};
component.ngOnChanges = function(changes: SimpleChanges) {
originalLifecycleHooks.ngOnChanges.call(this, changes);
lifecycles.ngOnChanges.next(changes);
};
component.ngOnInit = function() {
originalLifecycleHooks.ngOnInit.call(this);
lifecycles.ngOnInit.next();
lifecycles.ngOnInit.complete();
};
component.ngDoCheck = function() {
originalLifecycleHooks.ngDoCheck.call(this);
lifecycles.ngDoCheck.next();
};
component.ngOnDestroy = function() {
originalLifecycleHooks.ngOnDestroy.call(this);
lifecycles.ngOnDestroy.next();
lifecycles.ngOnDestroy.complete();
};
component.ngAfterContentInit = function() {
originalLifecycleHooks.ngAfterContentInit.call(this);
lifecycles.ngAfterContentInit.next();
lifecycles.ngAfterContentInit.complete();
};
component.ngAfterContentChecked = function() {
originalLifecycleHooks.ngAfterContentChecked.call(this);
lifecycles.ngAfterContentChecked.next();
};
component.ngAfterViewInit = function() {
originalLifecycleHooks.ngAfterViewInit.call(this);
lifecycles.ngAfterViewInit.next();
lifecycles.ngAfterViewInit.complete();
};
component.ngAfterViewChecked = function() {
originalLifecycleHooks.ngAfterViewChecked.call(this);
lifecycles.ngAfterViewChecked.next();
};
return {
ngOnChanges: key =>
lifecycles.ngOnChanges.pipe(
filter(changes => !!changes[key]),
map(changes => changes[key].currentValue),
takeUntil(lifecycles.ngOnDestroy)
),
ngOnInit: lifecycles.ngOnInit.pipe(takeUntil(lifecycles.ngOnDestroy)),
ngDoCheck: lifecycles.ngDoCheck.pipe(takeUntil(lifecycles.ngOnDestroy)),
ngOnDestroy: lifecycles.ngOnDestroy,
ngAfterContentInit: lifecycles.ngAfterContentInit.pipe(
takeUntil(lifecycles.ngOnDestroy)
),
ngAfterContentChecked: lifecycles.ngAfterContentChecked.pipe(
takeUntil(lifecycles.ngOnDestroy)
),
ngAfterViewInit: lifecycles.ngAfterViewInit.pipe(
takeUntil(lifecycles.ngOnDestroy)
),
ngAfterViewChecked: lifecycles.ngAfterViewChecked.pipe(
takeUntil(lifecycles.ngOnDestroy)
)
};
};
export abstract class ObservableLifecycles
implements OnChanges,
OnInit,
DoCheck,
OnDestroy,
AfterContentInit,
AfterContentChecked,
AfterViewInit,
AfterViewChecked {
lifecycle = observeLifecycles(this);
ngOnChanges(changes: SimpleChanges): void {}
ngOnInit(): void {}
ngDoCheck(): void {}
ngOnDestroy(): void {}
ngAfterContentInit(): void {}
ngAfterContentChecked(): void {}
ngAfterViewInit(): void {}
ngAfterViewChecked(): void {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment