Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Value from dropdown in Angular returns undefined

I have two dropdowns in separate child components, that are contained within a parent form component. The form component also contains an input field for quantity. On submit, the value for the quantity returns just fine, but the values from the dropdowns return undefined.

This is my form component:

export class BestelformulierComponent {
  selectedGroente: { naam: string, prijs: number };
  selectedWinkel: {naam:string};
  aantal: number;

  onGroenteSelected(groente: {naam:string, prijs:number}) {
    this.selectedGroente = groente;
  }
  
  onWinkelSelected(winkel: {naam:string}){
    this.selectedWinkel = winkel;
  }

  onSubmit() {
    console.log(this.selectedWinkel, this.aantal, this.selectedGroente);
  }
}

And the corresponding form html:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

<h1>Bestelformulier</h1>
<form #bestelFormulier="ngForm" (ngSubmit)="onSubmit()">
    <app-winkels (winkelSelected)="onWinkelSelected($event)"></app-winkels>
    <app-groenten (groenteSelected)="onGroenteSelected($event)"></app-groenten>
    <div>
        <label>Aantal/gewicht (stuk)</label>
        <input type="number" required [(ngModel)]="aantal" name="aantal">
    </div>
    <button type="submit" >Bestel</button>
</form>

The dropdown for stores:

export class WinkelsComponent implements OnInit{
  winkels: Winkel[] = [];

  @Output() winkelSelected = new EventEmitter<{naam:string}>();

  ngOnInit(): void {
    this.getWinkels();
  }

  getWinkels(): void {
    this.winkelService.getWinkels()
        .subscribe(winkels => this.winkels = winkels);
  }

  selectedWinkel: {naam:string}

  constructor(private winkelService: WinkelService){
      this.selectedWinkel = {naam: ''}
  }

  onWinkelSelected(){
    this.winkelSelected.emit(this.selectedWinkel);
  }
}

Stores dropdown html:

  <label for="winkelSelect">Kies winkel:</label>
  <select id="winkelSelect" [(ngModel)]="selectedWinkel" (change)="onWinkelSelected()">
    <option name="winkel" *ngFor="let winkel of winkels" [ngValue]="selectedWinkel" title="{{winkel.adres | titlecase}}, {{winkel.post}} {{winkel.gemeente}}">{{winkel.naam}}</option>
  </select>

And finally, the second dropdown (vegetables):

export class GroentenComponent implements OnInit {
  groentes: Groente[] = [];

  @Output() groenteSelected = new EventEmitter<{naam:string, prijs:number}>();

  constructor(private groenteService: GroenteService) {
    this.selectedGroente = {naam: '', prijs: 0};
  }

  ngOnInit(): void {
    this.getGroenten();
  }

  getGroenten(): void {
    this.groenteService.getGroentes()
        .subscribe(groentes => this.groentes = groentes);
  }

  selectedGroente: { naam: string, prijs: number }

  onGroenteSelected(){
    this.groenteSelected.emit(this.selectedGroente);
  }
}

Vegetable dropdown html:

    <label for="groenteSelect">Kies groente:</label>
    <select id="groenteSelect"  [(ngModel)]="selectedGroente" (change)="onGroenteSelected()">
        <option *ngFor="let groente of groentes" name="groente" [ngValue]="selectedGroente">{{groente.naam}} ({{groente.prijs}}/{{groente.eenheid}})</option>
    </select>
    

I’m guessing I messed up something with ngModel/ngValue? I’m totally new to Angular so I’m not sure if I misunderstood anything..

>Solution :

It looks like the issue is with how you are using [(ngModel)] and [ngValue] in your dropdowns.

In the WinkelsComponent, you are correctly using [ngValue] to bind the selected value to selectedWinkel. However, in the GroentenComponent, you are using [ngValue]="selectedGroente", which is binding the initial value of selectedGroente to each option. Instead, you should bind each option to the corresponding groente object using [ngValue]="groente".

Additionally, you are not setting the selectedWinkel and selectedGroente variables correctly in your components. You should set them to null or undefined instead of an empty object.

Here’s the updated code for GroentenComponent:

export class GroentenComponent implements OnInit {
  groentes: Groente[] = [];

  @Output() groenteSelected = new EventEmitter<{naam:string, prijs:number}>();

  selectedGroente: { naam: string, prijs: number };

  constructor(private groenteService: GroenteService) {}

  ngOnInit(): void {
    this.getGroenten();
  }

  getGroenten(): void {
    this.groenteService.getGroentes()
        .subscribe(groentes => this.groentes = groentes);
  }

  onGroenteSelected(){
    this.groenteSelected.emit(this.selectedGroente);
  }
}

And the updated HTML for GroentenComponent:

<label for="groenteSelect">Kies groente:</label>
<select id="groenteSelect" [(ngModel)]="selectedGroente" (change)="onGroenteSelected()">
    <option *ngFor="let groente of groentes" [ngValue]="groente">{{groente.naam}} ({{groente.prijs}}/{{groente.eenheid}})</option>
</select>

Note that the same changes should be applied to selectedWinkel and the WinkelsComponent.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading