angulardart / angular_components

The official Material Design components for AngularDart. Used at Google in production apps.
https://pub.dev/packages/angular_components
372 stars 123 forks source link

Type error on multiple selection with angular form #433

Closed e-belair closed 5 years ago

e-belair commented 5 years ago

Hi, I'm getting this error when I check a value in a multiple selection:

EXCEPTION: Type 'List<dynamic>' should be 'List<Filiere>' to implement expected type 'List<Filiere>'. .../... package:........./activite_component.template.dart 1117:10

<material-dropdown-select
        #filieres
        multi
        id="filieres"
        buttonText="Filières"
        [(ngModel)]="filiereVals"
        [options]="filiereOptions">
</material-dropdown-select>

In my component:

  StringSelectionOptions<Filiere> filiereOptions;
  List<Filiere> filiereVals = [];

I just reproduced the example from the offical example and I don't understand why the values are not cast in the good Type.

In the generated template dart file: I have this at line 1117:

  void _handle_ngModelChange_23_0($event) {
    final _ctx = ctx;
    _ctx.model.filieres = $event;
  }

Angular Components 0.14.0-alpha Angular forms 2.1.3 Dart 2.4

TedSander commented 5 years ago

Their is code generated for the template itself. It can't magically determine what type you want to use. So you would need to tell it in the Component annotation what types you want material-dropdown-select to be. Something like:

directiveTypes: [
    Typed<MaterialDropdownSelectComponent<Filiere>>(),
  ],
e-belair commented 5 years ago

Thank you for your answer. I didn't know about directiveTypes. I could solve it by specify the element on and specify also the value accessor class:

    directiveTypes: [
      Typed<MaterialDropdownSelectComponent<Filiere>>(on: 'filieres'),
      Typed<MultiDropdownSelectValueAccessor<Filiere>>(on: 'filieres'),
    ],

However, I encounter a problem when my model already contains values, the element does not check these values ans when I check on it, it consider these as new values.

image

I've customized the operator in my Filiere entity but nothing change:

class Filiere {
  String id;
  String libelle;

  Filiere();

  @override
  String toString() => libelle;

  @override
  bool operator ==(other) {
    return (other.id == id);
  }
}

The only way I found to get my values checked on Init form is to recreate the model selected values from the listOptions:

    _wcfService
        .getTableRefModel<Filiere>() // this method call the api to retrieve availables Filieres
        .then((t) {
          filiereOptions = StringSelectionOptions<Filiere>(t);
          // recreate selected values from t to get them checked
          filiereVals = t.where((f) => model.filieres.contains(f)).toList();
        });