21

I want to implement select menu which uses enum data to display data and saved number based on the selected String:

HTML code:

<div class="form-group state_raw">
    <label for="state_raw">State</label>
    <select class="custom-select" name="state_raw" [(ngModel)]="merchant.state_raw" id="state_raw" required>
      <option selected></option>
      <option [value]="type" *ngFor="let type of types">{{type | formatType}}</option>
    </select>
  </div>

Enum which displaying data and translated number value:

export enum MerchantStatusType {
  'Being set up' = 1,
  'Live for processing' = 2,
  'Trading suspended' = 3,
  'Account suspended' = 4
}

Object for the elect menu:

export class MerchantNew {
  constructor(
    public name: string,
    public address_state: string,
  ) {}
}

How can this be implemented? I want to display String but save number into database?

EDIT: I tried this:

ENUM:

export enum MerchantStateType {
  being_set_up = 1,
  live_for_processing = 2,
  trading_suspended = 3,
  account_suspended = 4,
}

export const MerchantStateType2LabelMapping = {
  [MerchantStateType.being_set_up]: "Being set up",
  [MerchantStateType.live_for_processing]: "Live for processing",
  [MerchantStateType.trading_suspended]: "Trading suspended",
  [MerchantStateType.account_suspended]: "Account suspended",
}

Component:

public MerchantStateType2LabelMapping = MerchantStateType2LabelMapping;

public stateTypes = Object.values(MerchantStateType);

HTML code:

<select class="custom-select" name="state_raw" [(ngModel)]="merchant.state_raw" id="state_raw" required>
      <!--<option selected></option>-->
      <option [value]="stateType" *ngFor="let stateType of stateTypes">{{ MerchantStateType2LabelMapping[stateType] }}</option>

But I get 4 empty rows and 4 lines of the states.

enter image description here

4
  • I do not know which part blocks you. It seems that you have it almost done. Please look at the sample in doc: angular.io/guide/dynamic-form#question-model. It might help you. Commented Dec 8, 2018 at 18:41
  • Can you show me how to use the enum into the html code? Commented Dec 8, 2018 at 19:22
  • @PeterPenzov: Can you show what are merchant and types? Commented Dec 8, 2018 at 19:31
  • Check this: stackoverflow.com/questions/38554562/… Commented Dec 8, 2018 at 19:35

5 Answers 5

43

I usually do it in 3 steps.

First, declare a separate enum and a mapping from the enum values to labels. This way both enum values and labels can be later changed just in one place without changing any other code.

// FileTypes.enum.ts

export enum FileTypesEnum {
    CSV = "CSV",
    JSON = "JSON",
    XML = "XML",
}

// optional: Record type annotation guaranties that 
// all the values from the enum are presented in the mapping
export const FileType2LabelMapping: Record<FileTypesEnum, string> = {
    [FileTypesEnum.CSV]: "Here's Csv",
    [FileTypesEnum.JSON]: "Here's Json",
    [FileTypesEnum.XML]: "Here's Xml",
};

Then import them into a component and stick them in a public property, so they will be available in the view:

// my.component.ts

import {FileTypesEnum, FileType2LabelMapping} from "../FileTypes.enum";

@Component({ ... })
export class MyComponent implements OnInit {
    public FileType2LabelMapping = FileType2LabelMapping;

    public fileTypes = Object.values(FileTypesEnum);

    constructor(){}
}

And then in the view i'm doing ngFor over enum's values and map them to labels:

 <!-- my.component.html -->

 <select ...>
  <option *ngFor="let fileType of fileTypes"
          [value]="fileType">
    {{FileType2LabelMapping[fileType]}}
  </option>
</select>

Update:

String-valued and numeric enums compile to different objects.

So it looks like you have to additionally filter your array

public stateTypes = Object.values(MerchantStateType).filter(value => typeof value === 'number');
Sign up to request clarification or add additional context in comments.

9 Comments

Thanks but I have a several words for key "Being set up" and you have CSV. How I can use it?
@PeterPenzov You can put this stuff in the label mapping and use a simple one-word identifier for enum key for easy-to-use
I found a bug. I get 4 empty lines and 4 values into the drop down list. Are you sure that your code is working properly?
@PeterPenzov I don't understand what whis means "But I get 4 empty rows and 4 lines of the states." Can you take a screenshot?
@PeterPenzov oh, I see. That's because I usually use string valued enums, not 1, 2, 3 You can see that they compile to the different shape. (My link is too long for a comment, so I'll add it to the answer, click Run and check the console). So you have to account for this shape when declaring public stateTypes =
|
22

Another simple way for Making Enum into dropdown or selecct List,

  1. Define Enum
export enum ConditionalOperator {
    Equals="Equals",
    NEquals="NEquals", 
    GT="GT", 
    GTE="GTE", 
    LT="LT", 
    }
  1. In component assign enum to a variable and in the constructor take all enum keys to another defined array
    conditionalOperator = ConditionalOperator;
    enumKeys=[];
    
    constructor(private fb: FormBuilder) {
      this.enumKeys=Object.keys(this.conditionalOperator);
    }
  1. And in the HTML file simply iterate through enum keys is an assign value as following,
    <select>
    <option value='' disabled selected>Operator</option>
    <option *ngFor="let name of enumKeys" [value]="name"> {{conditionalOperator[name]}} </option>
    </select>

2 Comments

this didn't work for me. First I had this error at enumKeys=[]: Type 'string[]' is not assignable to type 'never[]'. Type 'string' is not assignable to type 'never'. If I change the line to enumKeys: string[] = [] then I get this error on server start: conditionalOperator[name] gives error: No index signature with a parameter of type 'string' was found on type 'typeof ConditionalOperator'.
i had to add keyvalue pipe to the enum and use name.value to make it work
2
<div class="col-md-2">
    <label for="status">Status</label>
    <select id="status" [(ngModel)]="selected.status" class="form-select form-select-sm">
        <option *ngFor="let status of selected.statuses" [value]="status">
            {{ getName(status)}}
        </option>
    </select>
</div>
const getName = (status: String) => {
    return status == Status.UNDEFINED ? "UNDEFINED" : Object.values(Status)[Number(status)].toString();
}

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

if anyone using NG-ZORRO template.

Follow the above solution[Click], written by @mramsath

Then try this:

Update constructor or leave as it is. i updated for fetching values.

constructor(private fb: FormBuilder) {
      this.enumKeys=Object.values(this.conditionalOperator);
    }

Here is the main part:

<nz-select name="yourFormPostName" #yourFormPostName="ngModel" [(ngModel)]="data.yourFormPostName" nzPlaceHolder="Select Type" nzAllowClear style="width: 95%;">
<nz-option nzDisabled nzLabel="Select" nzValue="disabled"></nz-option>
<nz-option *ngFor="let name of enumKeys" [nzValue]="name" [nzLabel]="name"> </nz-option>
</nz-select>

Comments

0

In component ts :

function createEnum(values) {
      return {
        get: key => values[key],
        getAll: () => values
      };
    }
    
    const FileTypesEnum = createEnum({
        CSV = "CSV",
        JSON = "JSON",
        XML = "XML",
    });

in component html:

 <select ...>
  <option *ngFor="let fileType of fileTypes"
          [value]="fileType">
    {{FileTypesEnum.get(fileType)}}
  </option>
</select>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.