5

Why does this v-for loop over an enum show the names and values?

How can I iterate only over the keys?

export enum Colors {
  "RED" = 1,
  "BLUE" =  2,
  "GREEN" = 3,
}
<template>
   <div>
      <v-chip v-for="key in Colors" :key="key">{{key}}</v-chip>
   </div>
</template>

<script lang="ts">
import {Colors} from "./Enums"
import Vue from "vue";
export default Vue.extend({
  data: () => ({
     Colors,
  }),
});
</script>

This strangely results in 6 chips, but I would expect only 3.

  • RED
  • BLUE
  • GREEN
  • 1
  • 2
  • 3
4
  • Does this answer your question? Is there a simple way to get a list of keys/numbers from enum in typescript? Commented Jun 2, 2021 at 3:26
  • I think you have declared enum Colors as an Object. Commented Jun 2, 2021 at 3:27
  • @MattU no, Object.keys() doesn't fix this. Commented Jun 2, 2021 at 3:30
  • No, but it answers the question almost exactly as the answer on this question did. It still mentions how to filter the keys (e.g. filter out numeric keys). Commented Jun 2, 2021 at 3:43

2 Answers 2

2

Because v-for lists all properties of an object, it will show both the forward and reverse properties of the Typescript enum. You'll need to filter the keys yourself, possibly using Number.isInteger().

For context, Typescript enums get reverse mappings by default:

In addition to creating an object with property names for members, numeric enums members also get a reverse mapping from enum values to enum names. For example, in this example:

enum Enum {
  A,
}

let a = Enum.A;
let nameOfA = Enum[a]; // "A"

TypeScript compiles this down to the following JavaScript:

"use strict";
var Enum;
(function (Enum) {
  Enum[Enum["A"] = 0] = "A";
})(Enum || (Enum = {}));
let a = Enum.A;
let nameOfA = Enum[a]; // "A"

In this generated code, an enum is compiled into an object that stores both forward (name -> value) and reverse (value -> name) mappings. References to other enum members are always emitted as property accesses and never inlined.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks - how would I iterate over only the values? I've tried Object.keys/values and still get duplicated
Sorry, I'd overlooked that part originally. You'll need to filter the keys yourself, possibly using Number.isInteger().
@JeffBowman You could use v-for="(value, key, index) in myEnum" to have access to the values
@Tibike No, that's not the point. The point is that in a TypeScript enum we see Enum[Key]=Value and Enum[Value]=Key. Like my original syntax, your syntax would show both directions, which is not what the OP wanted.
@JeffBowman My mistake, my example used string literals for values not numbers.
1

Based on Jeff's answer, the code will look something like this:

<template>
    <div>
      <v-chip 
        v-for="([value, key], idx) in Object.entries(Colors).filter(([_, k]) => Number.isInteger(k))" 
        :key="idx"
      >
        {{ key }}
      </v-chip>
    </div>
</template>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.