angulardart/angular_components

material-input with ngControl directive

fmatuszewski opened this issue · 6 comments

I have recreated an example from ng_form_model.dart and tried to replace basic input with material-input

Right now material-input doesn't have value accessor which is used by ngControl directive which makes it incompatible with Reactive forms .

Is there a way to use material-inputs with ReactiveForms represented by ControlGroup class in angular dart world.

Material inputs value accessors are separated from the component so that it can be more flexible. For example translating a string -> number, string -> Int64, having the value written on blur instead of keystroke, etc.

If you are doing just a simple string input it is best to use this array of directives: https://github.com/dart-lang/angular_components/blob/c6cb3d783e72ff1ed7974f18b7f169778c73d39b/angular_components/lib/material_input/material_input.dart#L27

For a number this one: https://github.com/dart-lang/angular_components/blob/c6cb3d783e72ff1ed7974f18b7f169778c73d39b/angular_components/lib/material_input/material_number_accessor.dart#L22

It is not quite what I want I achieve.
I have a form

<form [ngFormModel]="loginForm">
    <input ngControl="login">
  <div ngControlGroup="passwordRetry">

    <p>Password<input type="password" ngControl="password"></p>
    <p>Confirm password <input type="password" ngControl="passwordConfirmation"></p>
  </div>
</form>
<h3>Form value:</h3>
<pre>{{value}}</pre>

ControlGroup loginForm;

PlacesComponent(){
loginForm = FormBuilder.controlGroup({
"login": ["", Validators.required],
"passwordRetry": FormBuilder.controlGroup({
"password": ["", Validators.required],
"passwordConfirmation": ["", Validators.required]
})
});

}

Which work perfeclty fine but I want to add material look and feel to it.
That is why I want to replace plain input with material-input but it is not compatible.

When I replaced input with material-input

<form [ngFormModel]="loginForm">
    <material-input ngControl="login"></material-input>
  <div ngControlGroup="passwordRetry">

      <p>Password<material-input material-input type="password" ngControl="password"></material-input></p>
      <p>Confirm password <material-input type="password" ngControl="passwordConfirmation"></material-input></p>
  </div>
</form>
<h3>Form value:</h3>
<pre>{{value}}</pre>

I get this error
EXCEPTION: Assertion failed: "No value accessor for (login) or you may be missing formDirectives in your directives list."
STACKTRACE:
dart:sdk_internal assertFailed
package:angular_forms/src/directives/shared.dart 25:28 setUpControl
package:angular_forms/src/directives/ng_form_model.dart 124:5

How can I fix it?

What does your directives list look like for that component? I'm pretty sure this pattern works we use it all the time.

Is there any good example for this anywhere?

This doesn't work for me and examples are using direct cotrol access ( [ngFormControl]=") which is not what we would expect. Angular app would work jsut as @fmatuszewski - you provide "parent group" on form level and use formControlName='nameOfKeyIngroup' to bind to the model. However here it is not working - because of reasons.

It should work just like that

https://angular.io/guide/reactive-forms#step-2-associating-the-formgroup-model-and-view