- The art of simplicity
- String enums
- How to use enum in HTML?
- Enums in Angular templates
- Transpilation
- Blog
- What is an Enum ?
- Creating an Enum
- Using an Enum in an Angular Component
- Convert a String to Enum in TypeScript
- Token Angular Component Code
- token.component.ts
- Source Code
- Conclusion
- You Might Also Like
- How to Implement Server-side Pagination with Angular and Spring Boot in 3 Steps
- How to Package Angular Application with Spring REST API
- How to Implement Spring Boot Angular User Registration Email Verification
- Leave a Reply Cancel reply
- Search
- Follow Us
- Subscribe to our Newsletter
- Categories
- Archives
- Popular Posts
- Recent Comments
The art of simplicity
Above, we have a numeric enum where Up is initialized with 1 . All of the following members are auto-incremented from that point on. In other words, Direction.Up has the value 1 , Down has 2 , Left has 3 , and Right has 4 .
Numeric enums can be mixed in computed and constant members (see below).
String enums
String enums are a similar concept, but have some subtle runtime differences as documented below. In a string enum, each member has to be constant-initialized with a string literal, or with another string enum member.
While string enums don’t have auto-incrementing behavior, string enums have the benefit that they “serialize” well. In other words, if you were debugging and had to read the runtime value of a numeric enum, the value is often opaque — it doesn’t convey any useful meaning on its own (though reverse mapping can often help), string enums allow you to give a meaningful and readable value when your code runs, independent of the name of the enum member itself.
In my situation I was using a Numeric enum but I wanted to display the related name on the screen(in my situation a Status value):
To display this value in a View I had to use some extra magic:
- First I had to import the enum in the corresponding component file:
- Next step was to create a public property on the component class that exposes this type:
- Now I can access this property on my view and get the enum string value:
- Get link
- Other Apps
How to use enum in HTML?
Sometimes you want to use an enum in the HTML template of an angular component.
Let’s say you have an OrderStatus enum and you want to show or hide elements based on whether the order status.
export enum OrderStatus Ordered, Processed, Shipped, Delivered, >
import Component, OnInit > from '@angular/core'; import OrderStatus > from '../order-status.enum'; @Component( selector: 'app-order-process', templateUrl: './order-process.component.html', styleUrls: ['./order-process.component.css'], >) export class OrderProcessComponent status = OrderStatus.Ordered; constructor() <> >
div *ngIf="orderStatus === OrderStatus.Ordered">Ordereddiv>
The code above will not compile:
error TS2339: Property 'OrderStatus' does not exist on type 'OrderProcessComponent'.
The problem is that the scope of the template is limited to the component instance members.
In order to get this to work, you need to defined a property in the component which value is the enum type.
import Component, OnInit > from '@angular/core'; import OrderStatus > from '../order-status.enum'; @Component( selector: 'app-order-process', templateUrl: './order-process.component.html', styleUrls: ['./order-process.component.css'], >) export class OrderProcessComponent // makes the OrderStatus enum available in the template OrderStatus = OrderStatus; status = OrderStatus.Ordered; constructor() <> >
Enums in Angular templates
The TypeScript enum can be used directly in your class, but it has to be assigned to a local variable to be used in the template.
import < Component >from '@angular/core'; enum LanguageType @Component(< selector: 'my-app', templateUrl: './app.component.html', styleUrls: [ './app.component.css' ] >) export class AppComponent < languageTypeDeclaredInComponent = LanguageType; constructor() < // this works console.log("Language Java", LanguageType.Java); // this works console.log("Language JavaScript", this.languageTypeDeclaredInComponent.JavaScript) >>
The template can work only with your local variable and not the enum self.
The template can access only objects exposed by the controller or the component.
OK, Enum for Java: languageTypeDeclaredInComponent.Java
OK, Validity: languageTypeDeclaredInComponent.Java === 1
KO, This doesn't work : LanguageType.Java
If you use directly the enum in the template the browser will show the following exception:
ERROR Error: Cannot read property [. ] of undefined
Transpilation
enum doesn’t exist in JavaScript. During the transpilation it’s converted in an array:
var ExampleType; (function (ExampleType) < ExampleType[ExampleType["Java"] = 1] = "Java"; ExampleType[ExampleType["JavaScript"] = 2] = "JavaScript"; ExampleType[ExampleType["TypeScript"] = 3] = "TypeScript"; >)(ExampleType || (ExampleType = <>)); ;
Blog
In our previous article, we have implemented user email verification based on a short-lived token. In this scenario, the token can have a different status like Valid, Invalid, Expired, etc., and based on this status, we had to render the view page. Hence, we have used an Enum for this use case to hold the different types of status. Now let’s dive deep to understand how to create a TypeScript Enum and use it in Angular components.
What is an Enum ?
Enums are one of the few features TypeScript has which is not a type-level extension of JavaScript. Enums allow a developer to define a set of named constants. Using enums can make it easier to document intent, or create a set of distinct cases. TypeScript provides both numeric and string-based enums.
Creating an Enum
We can either create the enum in a separate file or on the same component file outside the class. In our example, we have created the enum in the same token.component.ts file as shown below:
Using an Enum in an Angular Component
After creating the enum, we need to create a field in the component where we want to use this enum and assign it to the field:
Then, create a new field of type TokenStatus to hold the current status of the token:
Then, assign a value to the status field,
this.status = TokenStatus.VALID;
Then, in the component HTML file,
Email verified successfully. Please login.Link Expired!
Convert a String to Enum in TypeScript
In our application, we are validating the token in the backend REST API and getting the validation result in the response. This result will be VALID/INVALID/EXPIRED . Hence, instead of manually checking the string result returned in the JSON response, we have directly assigned the string value to the status field with the help of keyof and typeof operators. Now let’s understand what these operators are.
In Typescript, enums are used as types at compile-time to achieve type-safety for the constants but they are treated as objects at runtime. This is because they are converted to plain objects once the Typescript code is compiled to Javascript. Hence, in order to dynamically access an enum by a string key, we need to use the combination of keyof and typeof operators.
The keyof operator takes an object type and returns a type that accepts any of the object’s keys. it will return a union of string literals, each one is the key in the given object.
The typeof type operator can be used in a type context to refer to the type of a variable or property.
this.status = TokenStatus[data.message as keyof typeof TokenStatus];
Here, the typeof would return the type and the keyof will return a union of literal types («VALID» | «INVALID» | «EXPIRED» | «SENDING» | «SENT») that is made from the properties of type TokenStatus .
Note: Though Enums are treated as objects at runtime, when I tried with just the keyof operator, it worked fine. I couldn’t find an answer to this behavior. If you know, please do leave it in the comments section.
this.status = TokenStatus[data.message as keyof TokenStatus];
Token Angular Component Code
Here is the complete working code of the token component.
token.component.ts
import < Component, OnInit >from '@angular/core'; import < AuthService >from '../_services/auth.service'; import < Router, ActivatedRoute >from '@angular/router'; export enum TokenStatus < VALID, INVALID, EXPIRED, SENDING, SENT >@Component(< selector: 'app-token', templateUrl: './token.component.html', styleUrls: ['./register.component.css'] >) export class TokenComponent implements OnInit < token = ''; tokenStatus = TokenStatus; status : TokenStatus; errorMessage = ''; constructor(private authService: AuthService, private route: ActivatedRoute) < >ngOnInit(): void < this.token = this.route.snapshot.queryParamMap.get('token'); if(this.token)< this.authService.verifyToken(this.token).subscribe( data => < this.status = TokenStatus[data.message as keyof TokenStatus]; >, err => < this.errorMessage = err.error.message; >); > > resendToken(): void < this.status = TokenStatus.SENDING; this.authService.resendToken(this.token).subscribe( data => < this.status = TokenStatus.SENT; >, err => < this.errorMessage = err.error.message; >); > >
You can have a look at the token verification component section to understand how the enum is being accessed from the component HTML template.
Source Code
Conclusion
That’s all folks. In this article, we have explored how to use enums in angular components and how to convert a string from JSON to enum .
You Might Also Like
How to Implement Server-side Pagination with Angular and Spring Boot in 3 Steps
December 15, 2021
How to Package Angular Application with Spring REST API
January 16, 2021
How to Implement Spring Boot Angular User Registration Email Verification
Leave a Reply Cancel reply
Search
Follow Us
- Opens in a new tab
- Opens in a new tab
- Opens in a new tab
- Opens in a new tab
Subscribe to our Newsletter
Categories
Archives
- March 2023 (2)
- February 2023 (5)
- December 2022 (1)
- October 2022 (1)
- August 2022 (3)
- July 2022 (3)
- December 2021 (4)
- October 2021 (2)
- September 2021 (1)
- July 2021 (3)
- June 2021 (1)
- May 2021 (4)
- April 2021 (3)
- March 2021 (2)
- January 2021 (2)
- December 2020 (1)
- November 2020 (1)
- October 2020 (3)
- September 2020 (3)
- August 2020 (1)
- July 2020 (4)
- June 2020 (2)
- May 2020 (3)
- April 2020 (3)
- March 2020 (1)
- February 2020 (3)
- December 2019 (1)
- October 2019 (4)