Error in mat-select when I try to choose an item

0

Error:

  

ngModel can not be used to register form controls with a parent   formGroup directive. Try using         formGroup's partner directive "formControlName" instead. Example:

My HTML

<div class="container">
    <form [formGroup]="createForm" (ngSubmit)="postCreateFields()" style="width:400px; margin: 0 auto;">
      <h1>Create Fields</h1>

      <div class="required-field-block">
          <input formControlName="name" type="text" placeholder="Nome" class="form-control">
          <div class="required-icon">
              <div class="text">*</div>
          </div>
      </div>

      <div class="required-field-block">
          <input formControlName="typeField" type="text" placeholder="Field" class="form-control">
          <div class="required-icon">
              <div class="text">*</div>
          </div>
      </div>

      <div>
    <mat-form-field>
      <mat-select formControlName="typeField" placeholder="Type Fields" [(ngModel)]="dataSource" name="field">
        <mat-option  *ngFor="let field of dataSource" [value]="field.name">   
          {{field.name}}
        </mat-option>
      </mat-select>
    </mat-form-field>
  </div>

      <button type="submit" class="btn btn-primary" >Criar</button>
  </form>
  </div>

My component

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '../../../node_modules/@angular/forms';
import { CreateFieldsService } from '../Services/Fields/create-fields.service';

@Component({
  selector: 'app-create-fields',
  templateUrl: './create-fields.component.html',
  styleUrls: ['./create-fields.component.css'],
  providers: [CreateFieldsService]
})
export class CreateFieldsComponent implements OnInit {

  createForm :FormGroup;
  private _createFields: Model.CreateFields;

  selectedValue: string;
  private operUrl: 'api/TypesFields';
  public dataSource: Model.Itens[];

  constructor(private _createFieldService: CreateFieldsService, private builder: FormBuilder) { 
    this.createForm = this.builder.group({
     name: ''
   }) 
 } 

  ngOnInit() {

    this._createFieldService
    .getAll<Model.Result>()
    .subscribe((data: Model.Result) => {
      debugger;
      this.dataSource = data.itens;
    });

  }
  onPostCreateFields(){
    this._createFields = this.createForm.value;
    this._createFieldService.postCreateFields(this._createFields)
        .subscribe( success => {
          if(success.Result){
          }
        },
        error =>{
        }
      );
    }
}

How do I resolve this error? The error in the browser points to html line 13, referring to that: <input formControlName="typeField" type="text" placeholder="Field" class="form-control">

EDIT1

Actually the problem is in my mat-select, in this html line

<div>
    <mat-form-field>
      <mat-select formControlName="typeField" placeholder="Type Fields" [(ngModel)]="dataSource" name="field">
        <mat-option  *ngFor="let field of dataSource" [value]="field.name">   
          {{field.name}}
        </mat-option>
      </mat-select>
    </mat-form-field>
  </div>

EDIT2

I changed to this and did not give the error any more

<div>
        <mat-form-field>
          <mat-select formControlName="typeField" placeholder="Type Fields" [(ngModel)]="typeField" name="field">
            <mat-option  *ngFor="let field of dataSource" [value]="field.name">   
              {{field.name}}
            </mat-option>
          </mat-select>
        </mat-form-field>
      </div>

EDIT3

So my compoent stayed

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '../../../node_modules/@angular/forms';
import { CreateFieldsService } from '../Services/Fields/create-fields.service';

@Component({
  selector: 'app-create-fields',
  templateUrl: './create-fields.component.html',
  styleUrls: ['./create-fields.component.css'],
  providers: [CreateFieldsService]
})
export class CreateFieldsComponent implements OnInit {

  createForm :FormGroup;
  private _createFields: Model.CreateFields;

  selectedValue: string;
  private operUrl: 'api/Fields';
  public dataSource: Model.CreateTypeFieldItem[];

  constructor(private _createFieldService: CreateFieldsService, private builder: FormBuilder) { 
    this.createForm = this.builder.group({
     name: '',
     typeField:  ''

   });
 } 

  ngOnInit() {

    this._createFieldService
    .getAll<Model.Result<Model.CreateTypeFieldItem>>()
    .subscribe((data: Model.Result<Model.CreateTypeFieldItem>) => {
      debugger;
      this.dataSource = data.itens;
    });    
  }

  onPostCreateFields(){
    let formValue = this.createForm.value;
    this._createFields ={
      name: formValue.name,
      typeField: {
        typeFieldId: <string>formValue.typeField
      }
    };

    this._createFieldService.postCreateFields(this._createFields)
        .subscribe( success => {
          if(success.Result){
        }
      },
        error =>{
      }
    );
  }
}
    
asked by anonymous 18.07.2018 / 20:03

1 answer

1

I've put your code in to add comments on the changes I've made or need to make.

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms'; //arrumar import
import { CreateFieldsService } from '../Services/Fields/create-fields.service'; //not needed

@Component({
  selector: 'app-create-fields',
  templateUrl: './create-fields.component.html',
  styleUrls: ['./create-fields.component.css'],
  providers: [CreateFieldsService] // usa o providers do module, ou se for o angular 6 vc pode usar o provideIn: 'root' no proprio servico
})
export class CreateFieldsComponent implements OnInit {

  createForm :FormGroup;
  private _createFields: Model.CreateFields;

  selectedValue: string;
  private operUrl: 'api/TypesFields';
  dataSource: Model.Itens[];  // evite propriedade privadas ja que elas nao podem ser usadas no template.

  constructor(private _createFieldService: CreateFieldsService, private builder: FormBuilder) { 
//constructor sempre vazio, codigo de inicializacao ngOnInit
 } 

  ngOnInit() {
 //vc precisa de um control pra cada user input seja um select ou o que for.
this.createForm = this.builder.group({
     name: '', // -->seu input
     typeField: '' // -->seu select
   }) 

    this._createFieldService
    .getAll<Model.Result>()
    .subscribe((data: Model.Result) => {
      debugger;
      this.dataSource = data.itens;
    });

  }
  onPostCreateFields(){
    this._createFields = this.createForm.value;
    this._createFieldService.postCreateFields(this._createFields)
        .subscribe( success => {
          if(success.Result){
          }
        },
        error =>{
        }
      );
    }
}

Html - > remove all ngModel. Or you use the template forms or the reactiveForms

<mat-select formControlName="typeField" placeholder="Type Fields" name="field">
    <mat-option  *ngFor="let field of dataSource" [value]="field.name">   
      {{field.name}}
    </mat-option>
  </mat-select>
</mat-form-field>
    
19.07.2018 / 13:49