Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

Commit

Permalink
fix: 🐛 providing errorsModule in the lazy app module
Browse files Browse the repository at this point in the history
  • Loading branch information
DmitryEfimenko committed Jan 16, 2022
1 parent 87d624a commit b2f1488
Show file tree
Hide file tree
Showing 16 changed files with 104 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
ShowOnTouchedErrorStateMatcher,
} from './error-state-matchers';

@Injectable({ providedIn: 'root' })
@Injectable()
export class ErrorStateMatchers {
private matchers: { [key: string]: ErrorStateMatcher } = {};

Expand Down
7 changes: 5 additions & 2 deletions projects/ngx-errors/src/lib/error.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,13 @@ describe('ErrorDirective', () => {
Given(() => (showWhen = undefined as any));

function createDirectiveWithConfig(
showErrorsWhenInput: string,
showErrorsWhenInput: string | undefined,
showMaxErrors?: number
) {
const config: IErrorsConfiguration = { showErrorsWhenInput };
const config = new ErrorsConfiguration();
if (showErrorsWhenInput) {
config.showErrorsWhenInput = showErrorsWhenInput;
}
if (showMaxErrors !== undefined) {
config.showMaxErrors = showMaxErrors;
}
Expand Down
6 changes: 3 additions & 3 deletions projects/ngx-errors/src/lib/error.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ export class ErrorDirective implements AfterViewInit, OnDestroy {
err: any = {};

constructor(
private config: ErrorsConfiguration,
private errorStateMatchers: ErrorStateMatchers,
private overriddenShowWhen: OverriddenShowWhen,
private cdr: ChangeDetectorRef,
// ErrorsDirective is actually required.
// use @Optional so that we can throw a custom error
@Optional() private errorsDirective: ErrorsDirective,
@Optional() private config: ErrorsConfiguration
@Optional() private errorsDirective: ErrorsDirective
) {}

ngAfterViewInit() {
Expand Down Expand Up @@ -180,7 +180,7 @@ export class ErrorDirective implements AfterViewInit, OnDestroy {
return;
}

this.showWhen = this.config?.showErrorsWhenInput ?? 'touched';
this.showWhen = this.config.showErrorsWhenInput;

if (
this.showWhen === 'formIsSubmitted' &&
Expand Down
2 changes: 2 additions & 0 deletions projects/ngx-errors/src/lib/errors.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from '@angular/forms';
import { createDirectiveFactory, SpectatorDirective } from '@ngneat/spectator';
import { first } from 'rxjs/operators';
import { ErrorsConfiguration } from './errors-configuration';
import { ErrorsDirective } from './errors.directive';
import {
ControlNotFoundError,
Expand All @@ -32,6 +33,7 @@ describe('ErrorsDirective ', () => {
directive: ErrorsDirective,
host: TestHostComponent,
imports: [ReactiveFormsModule],
providers: [ErrorsConfiguration],
});

it('should throw if no control is provided', () => {
Expand Down
4 changes: 2 additions & 2 deletions projects/ngx-errors/src/lib/errors.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export class ErrorsDirective implements AfterViewInit {

const visible =
!errorCouldBeHidden &&
(!this.config?.showMaxErrors ||
(!this.config.showMaxErrors ||
visibleCount <= this.config.showMaxErrors);

arr.push({ key, hidden: !visible });
Expand All @@ -107,7 +107,7 @@ export class ErrorsDirective implements AfterViewInit {
constructor(
@Optional() @SkipSelf() public parentForm: FormGroupDirective | null,
@Optional() @SkipSelf() private parentFormGroupName: FormGroupName | null,
@Optional() private config: ErrorsConfiguration
private config: ErrorsConfiguration
) {}

ngAfterViewInit() {
Expand Down
18 changes: 11 additions & 7 deletions projects/ngx-errors/src/lib/errors.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
import { ModuleWithProviders, NgModule, Provider } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import {
ErrorStateMatcher,
Expand Down Expand Up @@ -35,16 +35,19 @@ function mergeErrorsConfiguration(
return { ...defaultConfig, ...config };
}

export const ERROR_STATE_MATCHER_PROVIDERS: Provider[] = [
ErrorStateMatchers,
ShowOnTouchedErrorStateMatcher,
ShowOnDirtyErrorStateMatcher,
ShowOnTouchedAndDirtyErrorStateMatcher,
ShowOnSubmittedErrorStateMatcher,
];

@NgModule({
imports: [ReactiveFormsModule],
declarations: [...declarationsAndExports],
exports: [...declarationsAndExports],
providers: [
ShowOnTouchedErrorStateMatcher,
ShowOnDirtyErrorStateMatcher,
ShowOnTouchedAndDirtyErrorStateMatcher,
ShowOnSubmittedErrorStateMatcher,
],
providers: [ErrorsConfiguration, ...ERROR_STATE_MATCHER_PROVIDERS],
})
export class NgxErrorsModule {
static configure(
Expand All @@ -53,6 +56,7 @@ export class NgxErrorsModule {
return {
ngModule: NgxErrorsModule,
providers: [
...ERROR_STATE_MATCHER_PROVIDERS,
{
provide: ErrorsConfiguration,
useValue: mergeErrorsConfiguration(config),
Expand Down
60 changes: 2 additions & 58 deletions projects/playground/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,13 @@
import { Injectable, NgModule } from '@angular/core';
import {
AbstractControl,
FormGroupDirective,
FormsModule,
NgForm,
} from '@angular/forms';
import { MatInputModule } from '@angular/material/input';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {
CUSTOM_ERROR_STATE_MATCHERS,
ErrorStateMatcher,
NgxErrorsModule,
} from '@ngspot/ngx-errors';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';

@Injectable({ providedIn: 'root' })
export class ShowOnDimaErrorStateMatcher implements ErrorStateMatcher {
isErrorState(
control: AbstractControl | null,
_form: FormGroupDirective | NgForm | null
): boolean {
return !!(control && control.value === 'dima');
}
}

@Injectable({ providedIn: 'root' })
export class ShowOnFiveErrorStateMatcher implements ErrorStateMatcher {
isErrorState(
control: AbstractControl | null,
_form: FormGroupDirective | NgForm | null
): boolean {
return !!(control && control.value && control.value.length === 5);
}
}

@NgModule({
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
FormsModule,
MatInputModule,
NgxErrorsModule.configure({
showErrorsWhenInput: 'dima',
}),
],
imports: [BrowserModule, AppRoutingModule, BrowserAnimationsModule],
declarations: [AppComponent, HomeComponent],
providers: [
{
provide: CUSTOM_ERROR_STATE_MATCHERS,
useFactory: (
showOnDirtyErrorStateMatcher: ShowOnDimaErrorStateMatcher,
showOnFiveErrorStateMatcher: ShowOnFiveErrorStateMatcher
) => {
return {
dima: showOnDirtyErrorStateMatcher,
five: showOnFiveErrorStateMatcher,
};
},
deps: [ShowOnDimaErrorStateMatcher, ShowOnFiveErrorStateMatcher],
},
],
bootstrap: [AppComponent],
})
export class AppModule {}
2 changes: 2 additions & 0 deletions projects/playground/src/app/custom-matchers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './show-on-dima-error-state-matcher';
export * from './show-on-five-error-state-matcher';
18 changes: 18 additions & 0 deletions projects/playground/src/app/custom-matchers/provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Provider } from '@angular/core';
import { CUSTOM_ERROR_STATE_MATCHERS } from '@ngspot/ngx-errors';
import { ShowOnDimaErrorStateMatcher } from './show-on-dima-error-state-matcher';
import { ShowOnFiveErrorStateMatcher } from './show-on-five-error-state-matcher';

export const CUSTOM_ERROR_STATE_MATCHERS_PROVIDER: Provider = {
provide: CUSTOM_ERROR_STATE_MATCHERS,
useFactory: (
showOnDirtyErrorStateMatcher: ShowOnDimaErrorStateMatcher,
showOnFiveErrorStateMatcher: ShowOnFiveErrorStateMatcher
) => {
return {
dima: showOnDirtyErrorStateMatcher,
five: showOnFiveErrorStateMatcher,
};
},
deps: [ShowOnDimaErrorStateMatcher, ShowOnFiveErrorStateMatcher],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Injectable } from '@angular/core';
import { AbstractControl, FormGroupDirective, NgForm } from '@angular/forms';
import { ErrorStateMatcher } from '@ngspot/ngx-errors';

@Injectable({ providedIn: 'root' })
export class ShowOnDimaErrorStateMatcher implements ErrorStateMatcher {
isErrorState(
control: AbstractControl | null,
_form: FormGroupDirective | NgForm | null
): boolean {
return !!(control && control.value === 'dima');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Injectable } from '@angular/core';
import { AbstractControl, FormGroupDirective, NgForm } from '@angular/forms';
import { ErrorStateMatcher } from '@ngspot/ngx-errors';

@Injectable({ providedIn: 'root' })
export class ShowOnFiveErrorStateMatcher implements ErrorStateMatcher {
isErrorState(
control: AbstractControl | null,
_form: FormGroupDirective | NgForm | null
): boolean {
return !!(control && control.value && control.value.length === 5);
}
}
25 changes: 0 additions & 25 deletions projects/playground/src/app/home/home.component.html
Original file line number Diff line number Diff line change
@@ -1,26 +1 @@
<p>home works!</p>

<mat-form-field appearance="fill">
<mat-label>Name</mat-label>

<input
matInput
[(ngModel)]="name"
required
[minlength]="10"
#nameModel="ngModel"
autocomplete="off"
/>

<mat-error [ngxErrors]="nameModel.control">
<span ngxError="required"> Name is required </span>

<span ngxError="minlength" showWhen="five">
Name should be at least 10 chars - FIVE
</span>

<span ngxError="minlength">Name should be at least 10 chars - DIMA</span>
</mat-error>
</mat-form-field>

<pre>{{ nameModel.control.errors | json }}</pre>
2 changes: 0 additions & 2 deletions projects/playground/src/app/home/home.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HomeComponent implements OnInit {
name: string;

constructor() {}

ngOnInit() {}
Expand Down
23 changes: 23 additions & 0 deletions projects/playground/src/app/lazy/lazy.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,26 @@

<button type="submit">Submit</button>
</form>

<mat-form-field appearance="fill">
<mat-label>Name</mat-label>

<input
matInput
[(ngModel)]="name"
required
[minlength]="10"
#nameModel="ngModel"
autocomplete="off"
/>

<mat-error [ngxErrors]="nameModel.control">
<span ngxError="required"> Name is required </span>

<span ngxError="minlength" showWhen="five">
Name should be at least 10 chars - FIVE
</span>

<span ngxError="minlength">Name should be at least 10 chars - DIMA</span>
</mat-error>
</mat-form-field>
3 changes: 3 additions & 0 deletions projects/playground/src/app/lazy/lazy.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import { dependentValidator } from '@ngspot/ngx-errors';
})
export class LazyComponent implements OnInit {
form: FormGroup;

name: string;

constructor(fb: FormBuilder) {
this.form = fb.group({
firstName: ['', Validators.required],
Expand Down
7 changes: 6 additions & 1 deletion projects/playground/src/app/lazy/lazy.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatInputModule } from '@angular/material/input';
import { NgxErrorsModule } from '@ngspot/ngx-errors';
import { CUSTOM_ERROR_STATE_MATCHERS_PROVIDER } from '../custom-matchers/provider';
import { LazyRoutingModule } from './lazy-routing.module';
import { LazyComponent } from './lazy.component';

Expand All @@ -11,9 +13,12 @@ import { LazyComponent } from './lazy.component';
CommonModule,
LazyRoutingModule,
ReactiveFormsModule,
FormsModule,
MatInputModule,
NgxErrorsModule.configure({
showErrorsWhenInput: 'touched',
}),
],
providers: [CUSTOM_ERROR_STATE_MATCHERS_PROVIDER],
})
export class LazyModule {}

0 comments on commit b2f1488

Please sign in to comment.