Skip to content

Commit

Permalink
fix(lib): Cannot read property 'nodeIndex' of null thrown when comp…
Browse files Browse the repository at this point in the history
…onent is being marked as dirty (with `markDirty` before the view is initialised
  • Loading branch information
maxime1992 committed Dec 30, 2020
1 parent 274420a commit 687ce21
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 13 deletions.
27 changes: 19 additions & 8 deletions projects/ngx-sub-form/src/lib/ngx-sub-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getObservableLifecycle } from 'ngx-observable-lifecycle';
import { EMPTY, forkJoin, merge, Observable, of, timer } from 'rxjs';
import {
delay,
exhaustMap,
filter,
map,
mapTo,
Expand Down Expand Up @@ -71,6 +72,7 @@ export function createForm<ControlInterface, FormInterface>(

const lifecyleHooks: ComponentHooks = options.componentHooks ?? {
onDestroy: getObservableLifecycle(componentInstance).ngOnDestroy,
afterViewInit: getObservableLifecycle(componentInstance).ngAfterViewInit,
};

lifecyleHooks.onDestroy.pipe(take(1)).subscribe(() => {
Expand Down Expand Up @@ -208,15 +210,24 @@ export function createForm<ControlInterface, FormInterface>(
formGroup.reset(value, { emitEvent: false });
}),
),
supportChangeDetectionStrategyOnPush: controlValue$.pipe(
delay(0),
tap(() =>
// support `changeDetection: ChangeDetectionStrategy.OnPush`
// on the component hosting a form
// fixes https://github.com/cloudnc/ngx-sub-form/issues/93
markDirty(componentInstance),
supportChangeDetectionStrategyOnPush:
// we need to wait first for the view to have been initialised
// otherwise calling `markDirty` previous to that throws an error
// `Cannot read property 'nodeIndex' of null`
// and the `delay(0)` doesn't give us that guarantee on its own
lifecyleHooks.afterViewInit.pipe(
exhaustMap(() =>
controlValue$.pipe(
delay(0),
tap(() =>
// support `changeDetection: ChangeDetectionStrategy.OnPush`
// on the component hosting a form
// fixes https://github.com/cloudnc/ngx-sub-form/issues/93
markDirty(componentInstance),
),
),
),
),
),
setDisabledState$: setDisabledState$.pipe(
tap((shouldDisable: boolean) => {
shouldDisable ? formGroup.disable({ emitEvent: false }) : formGroup.enable({ emitEvent: false });
Expand Down
2 changes: 1 addition & 1 deletion projects/ngx-sub-form/src/lib/ngx-sub-form.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import {
Controls,
ControlsNames,
NewFormErrors,
OneOfControlsTypes,
TypedFormGroup,
} from './shared/ngx-sub-form-utils';
import { FormGroupOptions } from './shared/ngx-sub-form.types';

export interface ComponentHooks {
onDestroy: Observable<void>;
afterViewInit: Observable<void>;
}

export interface FormBindings<ControlInterface> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { getObservableLifecycle } from 'ngx-observable-lifecycle';
import { createForm, FormType, subformComponentProviders } from 'ngx-sub-form';
import { DroidType, Languages, ProtocolDroid } from '../../../../../interfaces/droid.interface';

Expand All @@ -22,8 +21,5 @@ export class ProtocolDroidComponent {
droidType: new FormControl(DroidType.PROTOCOL, { validators: [Validators.required] }),
spokenLanguages: new FormControl(null, { validators: [Validators.required] }),
},
componentHooks: {
onDestroy: getObservableLifecycle(this).ngOnDestroy,
},
});
}

0 comments on commit 687ce21

Please sign in to comment.