angular 11 ngmodel not binding to select

Viewed 1218

In my Angular 11/TypeScript project I have the following model:

export interface Opponent {
    id: number;
    name: string;
    beltRank: BeltRankEnum;
    heightInInches: number;
    weightInLbs: number;    
}

export enum BeltRankEnum {
    White = 1,
    Blue = 2,
    Purple = 3,
    Brown = 4,
    Black = 5
}

const WHITE = "WHITE"
const BLUE = "BLUE"
const PURPLE = "PURPLE"
const BROWN = "BROWN"
const BLACK = "BLACK"

export const BeltRankToLabelMapping : Record<BeltRankEnum, string>  = {
    [BeltRankEnum.White]: WHITE,
    [BeltRankEnum.Blue]: BLUE,
    [BeltRankEnum.Purple]: PURPLE,
    [BeltRankEnum.Brown]: BROWN,
    [BeltRankEnum.Black]: BLACK,
}

export const LabelToBeltRankMapping = {
    WHITE: BeltRankEnum.White,
    BLUE: BeltRankEnum.Blue,
    PURPLE: BeltRankEnum.Purple,
    BROWN: BeltRankEnum.Brown,
    BLACK: BeltRankEnum.Black,
}

My component is:

    public opponent: Opponent = null;
    beltRankToLabelMapping = BeltRankToLabelMapping;
    labelToBeltRankMapping = LabelToBeltRankMapping;
    beltRanks = Object.values(BeltRankEnum).filter(f => !isNaN(Number(f)))

html snippet:

            <div class="form-group">
                <label class="beltRankLabel" for="beltRank">Belt Rank</label>
                <select [(ngModel)]="labelToBeltRankMapping[opponent.beltRank]">
                    <option *ngFor="let beltRank of beltRanks" 
                            [ngValue]="beltRank"> {{beltRankToLabelMapping[beltRank]}} </option>
                </select>
            </div>

The problem I'm having is that the drop down is not showing the beltRank Value for opponent. It's showing blank. Also, when I select an option from the drop down it's not setting it on the opponent model. Does anyone know what's going wrong? Thanks!

1 Answers

I think that can be your ngValue, that need to be changed to:

            <div class="form-group">
                <label class="beltRankLabel" for="beltRank">Belt Rank</label>
                <select [(ngModel)]="labelToBeltRankMapping[opponent.beltRank]">
                    <option *ngFor="let beltRank of beltRanks" 
                            [value]="beltRank"> {{beltRankToLabelMapping[beltRank]}} </option>
                </select>
            </div>

Edit:

The real problem in your code was that the select needs a name to receive a data in ngModel. Look this:

      <div class="form-group">
        <label class="beltRankLabel" for="beltRank">Belt Rank</label>
        <select [(ngModel)]="opponent.beltRank" name="beltRank">
                    <option *ngFor="let beltRank of beltRanks" 
                            [value]="beltRank"> {{beltRankToLabelMapping[beltRank]}} </option>
                </select>
      </div>

And I did a small change in ngModel passing "opponent.beltRank" to record the variable

Related