Angular ignores *ngFor in select option

Asked

Viewed 580 times

1

I’m trying to make a field like select in an Angular form with Materialize, and fill it dynamically, but when arriving at the directive *ngFor, Angular now ignores the field:

HTML:

    <!-- campo que não funciona -->
    <div class="input-field col s4">
      <select formControlName="item_id_dinamic">
        <option [ngValue]="" disabled selected>Escolha o item:</option>
        <option *ngFor="let item of itens" [ngValue]="item.id">{{ item.name }}</option>
      </select>
    </div>
    <!-- campo estático funcionando -->
    <div class="input-field col s4">
      <select formControlName="item_id_static">
        <option [ngValue]="" disabled selected>Escolha o banco:</option>
        <option [ngValue]="1">Opção 1</option>
        <option [ngValue]="2">Opção 2</option>
      </select>
    </div>

The result in the presentation of the fields is this:

Exemplo com opções estáticas e operacional

Use of static form options

Resultado usando opções geradas dinamicamente pela aplicação

Dynamically generated by the application

My Typescript component is mounted this way:

export class FormItensComponent implements OnInit {

  itens: Item[] = ITENS; // puxado array de outra parte da aplicação
  itemForm: FormGroup;

  constructor(
    private formBuilder: FormBuilder
  ){}

  ngOnInit() {
    // usado para inicializar o select com Materialize
    var elems = document.querySelectorAll('select');
    var instances = M.FormSelect.init(elems);
    this.itemForm = this.formBuilder.group({
      item_id_dinamic: ['', Validators.required],
      item_id_static:  ['', Validators.required]
    });
    /* detalhes de leitura de dados do banco omitidas */
  }
}

Example of possible items (JSON):

{
  id: 1,
  name: 'Item 1'
},
{
  id: 2,
  name: 'Item 2'
},
{
  id: 3,
  name: 'Item 3'
},
{
  id: 4,
  name: 'Outro'
}
  • 1

    ng-Model? example: https://stackoverflow.com/questions/30048605/angularjs-ng-model-in-a-select

  • 1

    I’m already using formControlName to do the integration part with the form (although it doesn’t appear in the code above), then Angular returns me this: It looks like you're using ngModel on the same form field as formControlName. &#xA; Support for using the ngModel input property and ngModelChange event with &#xA; reactive form directives has been deprecated in Angular v6 and will be removed &#xA; in Angular v7.

  • 1

    put all the example then ...

  • I updated the question with the implementation details

  • Send a JSON example also of Items doing favor.

  • Updated with JSON of sample items

  • Read: https://www.positronx.io/angular-7-select-dropdown-examples-with-reactive-forms/

Show 2 more comments

2 answers

1

I noticed a detail in your code, maybe it’s the cause. You declared the form variable itemForm: FormGroup with the name itemForm and initialized as bankAccountForm. I don’t know if it’s two different forms. I moved up an environment for testing assuming itemForm and everything happened normally (before changing the select was blank as in your example).

I made this change to your code:

ngOnInit() {
    this.itemForm = this.formBuilder.group({
      item_id_dinamic: ['', Validators.required],
      item_id_static:  ['', Validators.required]
    });
  }

Link to the stackblitz: https://stackblitz.com/edit/angular-nrifss

  • Good afternoon. I thank you for noticing the mistakes of the Ministry. I was so busy with the problem that I didn’t even touch myself when I was typing the example. But, unfortunately, this was not the problem. materialize, that is not being executed correctly.

  • The materialize was installed in the project using the node materialize-css and @types/materialize-css, and importing your Javascript into the component with the following code: import * as M from "materialize-css";

1


Good afternoon friend, there is great chance of the component initialization being in the wrong place the command:

var instances = M.FormSelect.init(elems);

should be executed after the data has already been loaded in select, if you bring the data in a Promise or observable stay tuned to this.

  • Interesting theory, I’ve even thought about it. However, when using as a solution (including using static data instead of pulling the API), the application continues to ignore the existence of the items. Below, my boot code:

  • ngOnInit() {&#xA; this.itens = [{&#xA; id: 1,&#xA; name: 'Item 1'&#xA;},&#xA;{&#xA; id: 2,&#xA; name: 'Item 2'&#xA;},&#xA;{&#xA; id: 3,&#xA; name: 'Item 3'&#xA;},&#xA;{&#xA; id: 4,&#xA; name: 'Outro'&#xA;}];&#xA; // usado para inicializar o select com Materialize&#xA; var elems = document.querySelectorAll('select');&#xA; var instances = M.FormSelect.init(elems);&#xA; this.itemForm = this.formBuilder.group({&#xA; item_id_dinamic: ['', Validators.required],&#xA; item_id_static: ['', Validators.required]&#xA; });&#xA; /* detalhes de leitura de dados do banco omitidas */&#xA; }

  • the drawing of the screen have to be fully ready, the loaded data and the rendered gift, you can not use ngOnInit in this case, just for test effect put this line that I highlighted inside a setTimeout with a few seconds, and check if the data appear

  • i have suffered from it already, and that was just the problem, even with static data, it is necessary to be all loaded, I used ngAfterViewChecked I think, or ran the code at the end of the Promise that brings the data

  • about the above code that you showed with static data, you are not considering that there is a bind to be made between this.items and the template via ngFor, javascript is single thread so any change of order compromises the result

  • 1

    achieved, was really this, using a setTimeout with an Arrow Function select is now working. Thank you.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.