Devextreme-angular: Question

Created on 12 Aug 2016  路  30Comments  路  Source: DevExpress/devextreme-angular

Hi,
I'm having problems using ngModel in DevEx components. For example, the following snippet:

<dx-number-box name="amt"
                   [(ngModel)]="selectedAmount"
                   id="amt"
                   [width]="200"
                   [mode]="number"
                   required
                   (keyup)="AmteventHandler($event)"
                   style="float: left;"
                   [showClearButton]="true">
</dx-number-box>

will result in the following error: "No value accessor for ''"

while a regular html input field like this:

name="amt"
type="number"
step="any"
[(ngModel)]="selectedAmount"
(keyup)="AmteventHandler($event)"
style="height: 30px; float: left"
required
/>

works without a glitch.
Any work-around or suggestions are highly welcome.

Best regards and thanks

question

All 30 comments

Hello!
Try to import the DxTextBoxValueAccessor
For other widgets, you also need to import additional directives

import { DxNumberBox, DxNumberBoxValueAccessor } from 'devextreme-angular2';
@Component({ ... directives: [ DxNumberBox, DxNumberBoxValueAccessor] })

Hi,
That is a good suggestion, but I'm afraid exactly the same situation appears. I still get the "No value accessor for ''" despite having added the Dx....ValueAcessor modules to both the import and directives. I have tried several of the components (DateBox, NumberBox, etc.), and I get the same error every time. Switching to [(value)] instead of [(ngModel)] does work though (as does the regular HTML input fields with [(ngModel)]), so I guess there's a glitch somewhere.

Hello,
We need more information to research the issue. Can you provide an example or a project where we can reproduce the problem?

Hi,

This is due to angular forms changes. Try this:
import {disableDeprecatedForms, provideForms} from '@angular/forms';

bootstrap(YourApp, [
聽 disableDeprecatedForms(),
聽 provideForms(),
聽 //other})
]);

import {REACTIVE_FORM_DIRECTIVES} from '@angular/forms';

If you are using forms 0.3

Have same issue MichaelGaihede mentioned. RC5, forms 0.3.0. [(value)] binding works fine but [(ngModel)] causes error: 'ngModel cannot be used to register form controls with a parent formGroup directive'.

Tried with DxDateBox.

  <dx-date-box
    id="input-drop-date"
    name="dropDate"
    [(ngModel)]="dropDate"
    [disabled]="isLoading || isProcessingUnderway"
    [pickerType]="calendar">
  </dx-date-box>

In the directives added: DxDateBoxValueAccessor, DxDateBox.

You should use formControlName instead of name.

Try this formControlName="dropDate" instead of name="dropDate"

When I switch it out to:

  <dx-date-box
    id="input-drop-date"
    formControlName="dropDate"
    [(value)]="dropDate"
    [disabled]="isLoading || isProcessingUnderway"
    [pickerType]="calendar">
  </dx-date-box>

The form is initialized as such:
constructor(
formBuilder: FormBuilder
) {
this.form = formBuilder.group({ 'dropDate': [''] });
}

and specified as:
<form [formGroup]="form">
in the template

I get:
ORIGINAL EXCEPTION: No value accessor for form control with name: 'dropDate'
ORIGINAL STACKTRACE:

I think that u are using template-drive-form and reactive forms. Choose one or make ngmodel standalone. This should help you:
https://github.com/angular/angular/pull/10314#issuecomment-242218563

I'm trying to reproduce the issue. If you change to dx-text-box, does it work?

Yes. It seems to be a bug in dx-number-box/dx-date-box and so on. It works with dx-text-box thats why they don't get the error in their example page.

Thanks for investigating this. Would we have an ETA when this would be fixed?

I'm not part of the devextreme team. It seems easy to solve. I think they should add ngDefaultControl to their custom imput components or maybe they have an old import to FORMS_DIRECTIVES. Maybe they should support [ngModelOptions]="{standalone: true} in their components. Seems Forms 0.3.0 support.

http://stackoverflow.com/questions/38958347/angular2-rc-5-custom-input-no-value-accessor-for-form-control-with-unspecified.

Im using the components without ngModel and FormGroup without problem at the moment:
<dx-number-box [(value)]="value"></dx-number-box>

Regards

Sounds good. Will wait on DevEx to respond with an ETA as I also had a issue open with their support.

Hello!

We have created an example and it works correctly.
Please clarify what steps we should perform to reproduce the error.

You are Rigth. It works. I had an old import in my complex project inside the directives array.
Thanks!

Edit: AND I Forgot to include dxdateBoxValueAccesor export in my Base NgModule.

@Angelminster What do you mean you forgot to add it to your base NgModule? That is not in the Plunker example.

I reviewed the Plunker example and even with exactly the same code, with everything stripped out I still get the error: ' No value accessor for form control with name: XXXXX'. The only distinction I can see between these projects is that mine is using Webpack rather then SystemJS.

Hi,

I have a module wrapping some external components. In this module i've declared all the Devextreme components and i import this module into other functional modules that i have. I forgot to include the valueAccesor in my exports.

BaseModule -> Import external libraries, commonModules, Shared... and Export them.
Module 1 -> Imports BaseModule.
Module 2 -> Imports BaseModule.

New Modules are ready to go with one import. Other developer teams need to get all the power of the core without being affected by component updates or changes. If i need a new Component i import it there and its available everywhere. A Good practice is to set all your shared services in one aditional module and inject it in your root module because of the injector scope in lazy routes (lazy routes creates another scope and the services are not shared between scopes). Some code of that module:

` declarations: [
[...]
DxDataGrid, DxPivotGrid, DxScheduler, DxPopup, DxButton, DxCheckBox, DxSwitch, DxTextBox, DxTextArea, DxNumberBox, DxDateBox, DxSlider, DxAutocomplete, DxSelectBox, DxTagBox, DxRadioGroup, DxCalendar, DxTemplate, DxLookup, DxTreeView, DxValidator, DxLoadIndicator, DxTooltip, DxPopover, DxMenu, DxMap, DxVectorMap, DxToolbar, DxChart, DxPieChart, DxTextBoxValueAccessor, DxNumberBoxValueAccessor, DxDateBoxValueAccessor, DxTextAreaValueAccessor, DxCheckBoxValueAccessor, DxAutocompleteValueAccessor, DxLookupValueAccessor, DxRadioGroupValueAccessor, DxSelectBoxValueAccessor, DxSliderValueAccessor, DxSwitchValueAccessor, DxTagBoxValueAccessor,
[...]
],

exports: [
[...],
DxDataGrid, DxPivotGrid, DxScheduler, DxPopup, DxButton, DxCheckBox, DxSwitch, DxTextBox, DxTextArea, DxNumberBox, DxDateBox, DxSlider, DxAutocomplete, DxSelectBox, DxTagBox, DxRadioGroup, DxCalendar, DxTemplate, DxLookup, DxTreeView, DxValidator, DxLoadIndicator, DxTooltip, DxPopover, DxMenu, DxMap, DxVectorMap, DxToolbar, DxChart, DxPieChart, DxTextBoxValueAccessor, DxNumberBoxValueAccessor, DxDateBoxValueAccessor, DxTextAreaValueAccessor, DxCheckBoxValueAccessor, DxAutocompleteValueAccessor, DxLookupValueAccessor, DxRadioGroupValueAccessor, DxSelectBoxValueAccessor, DxSliderValueAccessor, DxSwitchValueAccessor, DxTagBoxValueAccessor,
[...]
]
`
In a couple of weeks I'm going to switch to webpack2 but i don't think webpack is the problem here. Old Imports and Bad Import/Exports should be the issue. Maybe you have and old import inside the directives of any component (that was my problem) or forgot to export the *ValueAccessor to be used by the devextreme components inside of your ngModule.

It's a little tricky...

@Angelminster So if I understand correctly if any of our components use the old imports anywhere in our app then we will encounter the referenced error even if the component we are using DevEx has the correct imports?

Also *ValueAccessor have to be exported in a ngModule before being imported in a component?

Yes, I think so. You cannot mix old forms imports with new ones. You should import (ES6) only this:

import { FormsModule, ReactiveFormsModule } from '@angular/forms';
and in your appModule (The MainModule):
imports: [FormsModule, ReactiveFormsModule],

If you import FORMS_DIRECTIVES inside a component file (ES6 Import) and then set directives: [FORM_DIRECTIVES] inside Angular 2 Metadata, it breaks everything. There is only one way to manage forms (old or new). Inside the new way you can do it reactive and/or template driven forms.

Since the introduction of NgModule, the directives (that you already have in you components metadata) are registered automatically inside the module context. That's because backward compatibility and to set the correct context for the AoT (Ahead of Time) compiler.
Because of NgModule you don't need to import everything again in every component. That's one of the reason to create NgModule, its a pack of "features" to be used. If you have a component that belongs to a NgModule you have all the components (directives) already inside that component template without the need to import it again inside directives. So you can remove a lot of boilerplate thanks to this. You only need to import things that you are going to reference inside your class . Like:
@ViewChild(DxLookup) public dxLookupInstance: DxLookup;

Before ngModule in every component's directives you have to import dxButton, dxLookUp, etc... Not anymore. Import them in ngModule and use that module for the component and that's it.

I think that *valueAccessor only have to be exported once. In the mainModule for example. You cannot use anything in another module that is not exported before. It's like make it public for other modules to use it. One Component only belongs to one and only one NgModule. No circular references are allowed between modules.

I hope this helps you to solve the issue

@Angelminster Thanks for all your help, it is much appreciated. I reworked the whole DevEx stuff into a separate ngModule like your example and imported it into the main app ngModule. I removed all references to how the form directives where imported prior to RC5 (FORM_DIRECTIVES etc) and made sure the FormsModule, ReactiveFormsModule are loaded at the app ngModule as imports. Unfortunately no luck. The widget loads successfully now but the valueAccessor is still missing on it (debugged it). Angular still throws the error:

"No value accessor for form control with name: 'dropDate'"

After load

Are you using other libraries that could be using old form api?

@Angelminster : the only modules being imported into this project are:

DevExModule,
BrowserModule,
CommonModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
RouterModule.forRoot(rootRouterConfig)

I checked for any references to anything importing FORMS_DIRECTIVES or REACTIVE_FORM_DIRECTIVES. Found nothing beside @angular\forms and devextreme-angular2

Ok,

Angular 2 RC5? Angular Forms 0.3.0? Did you try to use normal input components instead of dx?

How do you declare the forms and de inputs? Try a simple solution and then use Dx*. care Name atribute of the input

 <form *ngIf="active" (ngSubmit)="onSubmit()" #heroForm="ngForm">
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name"
               required
               [(ngModel)]="model.name" name="name"
               #name="ngModel" >
        <div [hidden]="name.valid || name.pristine" 
             class="alert alert-danger">
          Name is required
        </div>
      </div>
</form>

If it's not possible to make it work...try to Remove the new Forms module imports and get the old one from import {DeprecatedFormsModule} from @angular/common;

Before
DevExModule, BrowserModule, CommonModule, FormsModule, ReactiveFormsModule, HttpModule, RouterModule.forRoot(rootRouterConfig)

After
DevExModule, BrowserModule, CommonModule, DeprecatedFormsModule, HttpModule, RouterModule.forRoot(rootRouterConfig)

Look at this plunker [http://plnkr.co/edit/bXH7IlegJpoh8k7DaLQD?p=preview]

Then remove in main.ts inside the declarations DxDateBoxValueAccessor and you get the error you have.

Really appreciate all your input. Yes to RC5 and Forms 0.3.0. Form works fine with normal inputs (DevEx widget is an extra input).

I see the Plucker demo and honestly at one point I had exactly that setup and it still gave that error. I guess the major difference was there are a few more things I imported from the forms framework:

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

I'll see if I can figure this out, or maybe just move to RC6 and see if it resolves itself.

Maybe there is bug somewhere...
One last thing: do you have your components inside the NgModule declarations array?

:-)

I just have the top level components declared in my NgModule declarations property.

Try to use the form in one of the Top Level Components. If it works, the valueAccessor does not propagate to the childs automatically. I don't know if that is a proper behaviour.

I think thats the key. If you don't put your components inside the declarations array, those components do not belong to that module and can't access the valueAccessor.
Option1: If you import *ValueAccessor inside component's directives array, it works?
Option1: Try to import all your components and set inside the declarations array.

We will get it! Don't give up! ^_^

Was this page helpful?
0 / 5 - 0 ratings