0

I have looked at questions like this one. But it doesn't quite answer my question. I want to bind the local variable name to the enum's value like in the following (heavily simplified) example:

In certain-state.component.ts:

export enum CertainState {
    VALID,
    INVALID
}

export class CertainStateComponent {
    // holder for the current state
    public state: CertainState;

    // store the actual enum in the instance of the class so that
    // it is available in the template
    public certainStates: typeof CertainState = CertainState;

    // below is the logic which sets the state
    ...
}

In certain-state.component.html:

<ng-container *ngTemplateOutlet="state_{{state}}"></ng-container>

// obviously this is invalid syntax but I want to demonstrate my intention
<ng-template #state_{{certainStates.VALID}}><span>VALID</span></ng-template>
<ng-template #state_{{certainStates.INVALID}}><span>INVALID</span></ng-template>

EDIT: I think the solution is in the following answer: How to use a typescript enum value in an Angular2 ngSwitch statement. What do you guys think?

2 Answers 2

3

This is what CertainState enum really is:

(function (CertainState) {
    CertainState[CertainState["VALID"] = 0] = "VALID";
    CertainState[CertainState["INVALID"] = 1] = "INVALID";
})(CertainState = exports.CertainState || (exports.CertainState = {}));

It basically maps keys to indexes and vice versa.

So it should be typed like:

public state: number;
public certainStates: typeof CertainState = CertainState;

And if state name is supposed to be used, it can be looked up on enum:

<ng-container *ngTemplateOutlet="state_{{certainStates[state]}}"></ng-container>
<ng-template #state_{{certainStates[certainStates.VALID]}}><span>VALID</span></ng-template>

Or enum index can be used directly:

<ng-container *ngTemplateOutlet="state_{{state}}"></ng-container>
<ng-template #state_{{certainStates.VALID}}><span>VALID</span></ng-template>

Enums aren't the best choice for cases where a key may be used as a string, because they require extra lookup and don't allow strict typing. As explained here, plain object is generally a better choice for looser typing, and a namespace is good for stricter typing.

0
public certainStates: typeof CertainState = CertainState;

should be

public certainStates: any = CertainState;

or

public certainStates: {[s: number]: string } = CertainState;
4
  • Your solution throws "Type 'typeof CertainState' is not assignable to type 'CertainState'."
    – Tom
    Commented Sep 11, 2017 at 7:56
  • I updated my answer. See also stackoverflow.com/a/30785209/217408 Commented Sep 11, 2017 at 8:01
  • Why so? typeof CertainState is valid type and should work as expected. Commented Sep 11, 2017 at 8:56
  • Seems to be passed as object, not as type in an assignment. Commented Sep 11, 2017 at 8:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.