Solvedangular Use more than one CustomValueAcessor in one Input field

I'm submitting a ... (check one with "x")

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior
I have created 2 directives with a CustomValueAcessor, and when I use them in an field I got the following error:

Error: Uncaught (in promise): Error: More than one custom value accessor matches form control with unspecified name attribute

Expected behavior
The input field should accept more than 2 CustomValueAcessor

Minimal reproduction of the problem with instructions

http://plnkr.co/edit/zPz40DNYmAO7mokJ09a9?p=preview

Please tell us about your environment:

"dependencies": {
"@angular/animations": "^4.1.0",
"@angular/cli": "^1.0.0-beta.28.3",
"@angular/common": "^4.1.0",
"@angular/compiler": "^4.1.0",
"@angular/compiler-cli": "^4.1.0",
"@angular/core": "^4.1.0",
"@angular/forms": "^4.1.0",
"@angular/http": "^4.1.0",
"@angular/platform-browser": "^4.1.0",
"@angular/platform-browser-dynamic": "^4.1.0",
"@angular/platform-server": "^4.1.0",
"@angular/router": "^4.1.0"
}

  • Angular version: 2.0.X
  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
  • Language: [all | TypeScript X.X | ES6/7 | ES5]

  • Node (for AoT issues): node --version =

17 Answers

✔️Accepted Answer

As mentioned above, text-mask won't work with material2. A workaround is to use the vanilla version of text-mask:
1 - Import the library in your component
import * as textMask from "vanilla-text-mask/dist/vanillaTextMask.js";

2 - Add your mask in the component and init your input (don't forget to import AfterViewInit and implement it to your component)

  mask = [ /[1-9]/, /\d/, /\d/];
  maskedInputController;

  @ViewChild("input", { read: ViewContainerRef }) public input;

  ngAfterViewInit(): void {
    setTimeout(() => {
      this.maskedInputController = textMask.maskInput({
        inputElement: this.input.element.nativeElement,
        mask: this.mask
      });
    });
  }

  ngOnDestroy() {
    this.maskedInputController.destroy();
  }

3 - in your template, make sure the input element has an #input attribute

<mat-form-field class="input">
  <input matInput [matDatepicker]="picker" [(ngModel)]="selectedValue" #input>
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

Other Answers:

i have a solution with a directive using the solution of @remborg

import { Directive, ElementRef, OnDestroy } from '@angular/core';
import * as textMask from 'vanilla-text-mask/dist/vanillaTextMask.js';

@Directive({
  selector: '[appMaskDate]'
})
export class MaskDateDirective implements OnDestroy {

  mask = [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/]; // dd/mm/yyyy
  maskedInputController;

  constructor(private element: ElementRef) {
    this.maskedInputController = textMask.maskInput({
      inputElement: this.element.nativeElement,
      mask: this.mask
    });
  }

  ngOnDestroy() {
    this.maskedInputController.destroy();
  }

}

<input matInput formControlName="FechaInicio" [matDatepicker]="FechaInicioRef" placeholder="Fecha Inicio" appMaskDate>

I also have this issue. ionic4 + angular 7 + ngx-mask:
<input matInput [matDatepicker]="picker" mask="XXX/X0/0000" formControlName="idIssueDate" required>
results in:
ERROR Error: Uncaught (in promise): Error: More than one custom value accessor matches form control with unspecified name attribute Error: More than one custom value accessor matches form control with unspecified name attribute at _throwError (forms.js:2144) at forms.js:2202 at Array.forEach (<anonymous>) at selectValueAccessor (forms.js:2191) at new FormControlName (forms.js:5782) at createClass (core.js:22160) at createDirectiveInstance (core.js:22029) at createViewNodes (core.js:23255) at callViewAction (core.js:23571) at execComponentViewsAction (core.js:23490) at resolvePromise (zone.js:831) at resolvePromise (zone.js:788) at zone.js:892 at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423) at Object.onInvokeTask (core.js:17290) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422) at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195) at drainMicroTaskQueue (zone.js:601)

@remborg @brandon1525 You didn't have any issues with the synchronization between the text-mask value and the datepicker value ?

I put an example on stackblitz to illustrate my issue

If you type manually and quickly 14, you will see in the errors that the value is 14_/__/____ instead of 14/__/____. If you continue, you will have 14/03/2018_....which is indeed incorrect for the date picker but in your field the value is correct....

More Issues: