{"id":13808596,"url":"https://github.com/dgonzalez870/ngx-formcontrol-errors","last_synced_at":"2026-01-25T03:06:56.175Z","repository":{"id":226674411,"uuid":"768898154","full_name":"dgonzalez870/ngx-formcontrol-errors","owner":"dgonzalez870","description":"A directive for showing errors in Angular form controls","archived":false,"fork":false,"pushed_at":"2025-08-13T11:53:08.000Z","size":1260,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-13T13:15:33.085Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dgonzalez870.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-03-07T23:51:42.000Z","updated_at":"2025-08-13T11:53:05.000Z","dependencies_parsed_at":"2024-03-08T23:27:37.260Z","dependency_job_id":"26e78acd-600c-49ee-a9c7-b926d5d1dcd7","html_url":"https://github.com/dgonzalez870/ngx-formcontrol-errors","commit_stats":null,"previous_names":["dgonzalez870/ngx-formcontrol-errors"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/dgonzalez870/ngx-formcontrol-errors","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgonzalez870%2Fngx-formcontrol-errors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgonzalez870%2Fngx-formcontrol-errors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgonzalez870%2Fngx-formcontrol-errors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgonzalez870%2Fngx-formcontrol-errors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dgonzalez870","download_url":"https://codeload.github.com/dgonzalez870/ngx-formcontrol-errors/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgonzalez870%2Fngx-formcontrol-errors/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28742973,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T02:46:29.005Z","status":"ssl_error","status_checked_at":"2026-01-25T02:44:29.968Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T01:01:47.047Z","updated_at":"2026-01-25T03:06:56.169Z","avatar_url":"https://github.com/dgonzalez870.png","language":"TypeScript","funding_links":[],"categories":["Third Party Components"],"sub_categories":["Form Validation"],"readme":"# NgxFormControlErrorsMsgs\n\n![NPM Version](https://img.shields.io/npm/v/ngx-formcontrol-errors-msgs)\n![code coverage](https://dgonzalez870.github.io/ngx-formcontrol-errors/core-coverage-badge.svg)\n![build test deploy](https://github.com/dgonzalez870/ngx-formcontrol-errors/actions/workflows/static.yml/badge.svg)\n\nThis is a directive that provides an uncomplicated way to display [Angular ValidationErrors](https://angular.io/api/forms/ValidationErrors) in [Reactive Forms](https://angular.io/guide/reactive-forms)\n\nSee It working on this [demo](https://dgonzalez870.github.io/ngx-formcontrol-errors/).\n\nYou can also try it in your browser [here](https://stackblitz.com/edit/stackblitz-starters-xmrsdr?file=src%2Fapp%2Fapp.component.ts).\n\n## Installation\n\n`npm install --save ngx-formcontrol-errors-msgs`\n\n## Usage\n\n1. Import `FormcontrolErrorsDirective` in the component (You must import [ReactiveFormsModule](https://angular.io/api/forms/ReactiveFormsModule) too)\n\n```typescript\nimport { Component } from '@angular/core';\nimport { FormBuilder, ReactiveFormsModule, Validators } from \"@angular/forms\";\n\nimport { FormcontrolErrorsDirective } from \"ngx-formcontrol-errors-msgs\";\n\n@Component({\n  selector: 'app-form',\n  standalone: true,\n  imports: [FormcontrolErrorsDirective, ReactiveFormsModule],\n  templateUrl: './app-form.component.html',\n  styleUrl: './app-form.component.scss',\n})\nexport class AppForm {\n\n  constructor(private readonly formBuilder: FormBuilder) {}\n\n  ...\n}\n```\n\n2. Create a form as usual for Reactive Forms\n\n```typescript\nform = this.formBuilder.group({\n  name: [\"\", [Validators.required, Validators.maxLength(10)]],\n  email: [\"\", [Validators.required, Validators.email]],\n});\n```\n\n3. Place the directive in the template along with [FormControlName](https://angular.io/api/forms/FormControlName) or\n[FormControl](https://angular.io/api/forms/FormControl)\n\n```html\n\u003cform [formGroup]=\"form\"\u003e\n  \u003cdiv class=\"form-row\"\u003e\n    \u003clabel for=\"name\"\u003eName\u003c/label\u003e\n    \u003cinput id=\"name\" type=\"text\" formControlName=\"name\" ngxFormcontrolErrors /\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"form-row\"\u003e\n    \u003clabel for=\"email\"\u003eEmail\u003c/label\u003e\n    \u003cinput id=\"email\" type=\"email\" formControlName=\"email\" ngxFormcontrolErrors /\u003e\n  \u003c/div\u003e\n\u003c/form\u003e\n```\n\n**Note:** :warning: This module does not provide any CSS stylesheet, see [Styling](#styling). CSS classes in the previous code are only for example purposes and are not required.\n\n## Customize Messages\n\nBy default this module provides the following messages for\n[Angular built-in Validators](https://angular.io/api/forms/Validators):\n\n```typescript\nexport const Messages: KeyValueObject = {\n  required: \"This field is required\",\n  min: \"The minimun allowed values is {{min}}\",\n  max: \"The max allowed value is {{max}}\",\n  minlength: \"The minimun allowed length is {{requiredLength}}\",\n  maxlength: \"The max allowed length is {{requiredLength}}\",\n  email: \"Invalid email\",\n  pattern: \"Invalid pattern\",\n};\n```\n\nWhere `KeyValueObject` is custom type defined by:\n\n```typescript\nexport type KeyValueObject = { [key: string]: string };\n```\n\nStrings enclosed in double brackets, like `{{min}}`, `{{max}}`, `{{requiredLength}}`, are replaced at runtime by the actual validation reference value.\nThose messages can be overrided or extended by injecting new ones using\n`FORM_ERROR_MESSAGES_PROVIDER` in the [ApplicationConfig](https://angular.io/api/core/ApplicationConfig) object.\n\n```typescript\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    ...\n    {\n      provide: FORM_ERROR_MESSAGES_PROVIDER,\n      useValue: {\n        // This message will override the default message\n        required: \"This is a \u003cb\u003erequired\u003c/b\u003e field\",\n        // This is a message for a custom validator and will extend the default\n        // messages\n        myCustomValidation: \"There is an error\",\n      },\n    },\n    ...\n  ],\n};\n```\n\nHTML tags are allowed.\n\n## Internationalization (I18N)\n\n### 1. Angular I18N\n\nIf the application uses [Angular Internationalization](https://angular.io/guide/i18n-overview),\n`FORM_ERROR_MESSAGES_PROVIDER` could be provided using `$localize` after adding all necessary settings for\n**Angular I18N**\n\n```typescript\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    ...\n    {\n      provide: FORM_ERROR_MESSAGES_PROVIDER,\n      useValue: {\n        required: $localize `This field is required`,\n        min: $localize `The minimun allowed values is {{min}}`,\n        max: $localize `The max allowed value is {{max}}`,\n        minlength: $localize `The minimun allowed length is {{requiredLength}}`,\n        maxlength: $localize `The max allowed length is {{requiredLength}}`,\n        email: $localize `Invalid email`,\n        pattern: $localize `Invalid pattern`,\n      },\n    },\n    ...\n  ],\n};\n```\n\n### 2. NGX-TRANSLATE\n\nIf the application uses [ngx-translate](https://github.com/ngx-translate/core), the following settings are required:\n\n1. Install the [message parser service for `ngx-translate`](https://www.npmjs.com/package/ngx-formcontrol-msgs-translate-parser)\n\n```sh\nnpm install --save ngx-formcontrol-msgs-translate-parser\n```\n\n2. Provide `ERROR_MSG_COMPONENT_FACTORY` in `ApplicationConfig` using class `TranslateErrorMsgComponentFactoryService`\n\n```typescript\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    ...\n    {\n      provide: ERROR_MSG_COMPONENT_FACTORY,\n      useClass: TranslateErrorMsgComponentFactoryService,\n    },\n    ...\n  ],\n};\n```\n\n3. Add the messages in the locale file of each language (as usual for `ngx-translate`)\n\n**English (en.json)**\n\n```json\n{\n  ...\n  \"FORM_ERROR_MESSAGES\": {\n    \"REQUIRED\": \"This field is required\",\n    \"MIN\": \"The minimun allowed values is {{min}}\",\n    \"MAX\": \"The max allowed value is {{max}}\",\n    \"MINLENGTH\": \"The minimun allowed length is {{requiredLength}}\",\n    \"MAXLENGTH\": \"The max allowed length is {{requiredLength}}\",\n    \"EMAIL\": \"Invalid email\",\n    \"PATTERN\": \"Invalid pattern\",\n    \"CUSTOM\": \"Ups, something went wrong\",\n    ...\n  }\n  ...\n}\n```\n\n**Spanish (es.json)**\n\n```json\n{\n  ...\n  \"FORM_ERROR_MESSAGES\": {\n    \"REQUIRED\": \"Este campo es obligatorio\",\n    \"MIN\": \"El mínimo valor permitido es {{min}}\",\n    \"MAX\": \"El máximo valor permitido es {{max}}\",\n    \"MINLENGTH\": \"El mínimo número de caracteres es {{requiredLength}}\",\n    \"MAXLENGTH\": \"El máximo número de caracteres es {{requiredLength}}\",\n    \"EMAIL\": \"Email inválido\",\n    \"PATTERN\": \"Entrada inválida\",\n    \"CUSTOM\": \"Ups, Algo salió mal\",\n    ...\n  }\n  ...\n}\n```\n\n4. Provide `FORM_ERROR_MESSAGES_PROVIDER` referencing the values in the locale files\n\n```typescript\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    ...\n    {\n      provide: FORM_ERROR_MESSAGES_PROVIDER,\n      useValue: {\n        required: \"FORM_ERROR_MESSAGES.REQUIRED\",\n        min: \"FORM_ERROR_MESSAGES.MIN\",\n        max: \"FORM_ERROR_MESSAGES.MAX\",\n        minlength: \"FORM_ERROR_MESSAGES.MINLENGTH\",\n        maxlength: \"FORM_ERROR_MESSAGES.MAXLENGTH\",\n        email: \"FORM_ERROR_MESSAGES.EMAIL\",\n        pattern: \"FORM_ERROR_MESSAGES.PATTERN\",\n        custom: \"FORM_ERROR_MESSAGES.CUSTOM\",\n        ...\n      },\n    },\n    ...\n  ],\n};\n```\n\n### 3. Other I18N methods\n\nIf the application uses I18N methods other than [NGX-TRANSLATE](#2-ngx-translate) or [Angular I18N](#1-angular-i18n), there are two posible aproaches: [service driven](#31-service-driven), [component driven](#32-component-driven)\n\n#### 3.1 Service driven\n\n1. Create a class or service that implements `ErrorMsgParser` and override the method `parse` to return customized translations that could reliy on a custom I18N service\n\n```typescript\n\n@Injectable({\n  ...\n})\nexport class CustomMsgParserService implements ErrorMsgParser {\n  constructor(\n    private readonly i18nService: CustomI18NService,\n    @Inject(FORM_ERROR_MESSAGES_PROVIDER)\n    private customErrorMessages: KeyValueObject\n  ) {}\n\n  parse(error: ValidationErrors): string {\n    ...\n    // Develop the logic to translate `customErrorMessages` using `CustomI18NService`\n    ...\n  }\n}\n\n```\n\n2. Provide `ERROR_MSG_PARSER` in `ApplicationConfig` using the custom class created in the previous step.\n\n```typescript\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    ...\n    {\n      provide: ERROR_MSG_PARSER,\n      useClass: CustomMsgParserService,\n    },\n    ...\n  ],\n};\n```\n\n#### 3.2 Component Driven\n\nSelect component driven aproach whenever you want to use any existing `pipe`, like the `translate` pipe available in `ngx-translate`, this way you can provide a custom component that uses the already available pipes.\n\n1. Create a component class that implements `ErrorMsgComponent`\n\n```typescript\n\n@Component({\n  ...\n})\nexport class CustomErrorMsgComponent implements ErrorMsgComponent {\n\n  @Input()\n  messages: ErrorMessage[];\n\n  ...\n}\n```\n\n`ErrorMessage` is an **interface** with two properties:\n\n```typescript\nexport interface ErrorMessage {\n  /**\n   * String to be displayed, customized or translated\n   */\n  message: string;\n\n  /**\n   * ValidationError content to be replaced in the `message` string\n   */\n  value?: unknown;\n}\n```\n\n2. Create a service that implements `ErrorMessageComponentFactory`, the `createComponent` method should return a `ComponentRef` of the component created in the previous step\n\n```typescript\n@Injectable({\n  ...\n})\nexport class CustomMsgComponentFactoryService\n  implements ErrorMessageComponentFactory\n{\n  constructor() {}\n\n  createComponent(viewContainerRef: ViewContainerRef): ComponentRef\u003cCustomErrorMsgComponent\u003e {\n    return viewContainerRef.createComponent(CustomErrorMsgComponent);\n  }\n\n}\n\n```\n\n3. Provide `ERROR_MSG_COMPONENT_FACTORY` in `ApplicationConfig` using class `CustomMsgComponentFactoryService` (created in the previous step)\n\n```typescript\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    ...\n    {\n      provide: ERROR_MSG_COMPONENT_FACTORY,\n      useClass: CustomMsgComponentFactoryService,\n    },\n    ...\n  ],\n};\n```\n\n## Styling\n\nThis module does not provide any CSS stylesheet or settings,\nso a custom style must be applied to fit the look and feel of the application.\n\nThis directive attaches a `ngx-formcontrol-errors` component as siblings of the `input` elements,\nstyles to those components can be applied globally in the `styles.scss` of the application\n\n```css\n:root {\n  --error-color: #ff0000;\n}\n\nngx-formcontrol-errors {\n  display: block;\n  font-size: 0.75rem;\n  color: var(--error-color);\n  text-align: right;\n  min-height: 1rem;\n}\n```\n\nStyles can also be applied at component level using `ng-deep`\n\n```css\n::ng-deep ngx-formcontrol-errors {\n  display: block;\n  font-size: 0.75rem;\n  color: var(--error-color);\n  text-align: right;\n  min-height: 1rem;\n}\n```\n\nIf you create a Custom error component like in [Component driven](#32-component-driven), you have to replace `ngx-formcontrol-errors` for your custom component selector.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgonzalez870%2Fngx-formcontrol-errors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdgonzalez870%2Fngx-formcontrol-errors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgonzalez870%2Fngx-formcontrol-errors/lists"}