DEV Community

Manthan Ankolekar
Manthan Ankolekar

Posted on

Building an Angular App with Enum Alternatives - A Hands-On Guide

Let's create a simple Angular app that demonstrates how to use enum alternatives to manage related constants. Enum alternatives offer flexibility and type safety when working with a small set of constants in TypeScript. In this guide, we'll walk through the process of building an Angular app that uses various enum alternatives to manage user statuses and roles.

Step 1: Set Up the Angular App

Create a new Angular project and navigate into it:

ng new enum-alternatives-app
cd enum-alternatives-app
Enter fullscreen mode Exit fullscreen mode

Generate two components that will demonstrate different ways to handle user statuses and roles:

ng generate component UserStatus
ng generate component UserRole
Enter fullscreen mode Exit fullscreen mode

Step 2: Define Enum Alternatives

In the src/app directory, create a folder named types to keep your enum alternatives organized:

mkdir src/app/types
Enter fullscreen mode Exit fullscreen mode

Then, create the following files inside the types folder to define each enum alternative.

1. Union Type (types/user-status.type.ts)

Define a union type to represent user statuses:

export type UserStatusType = 'Active' | 'Inactive' | 'Pending';
Enter fullscreen mode Exit fullscreen mode

2. Constant Object (types/status.constant.ts)

Define a constant object with as const for user statuses:

export const STATUS = {
  Active: 'Active',
  Inactive: 'Inactive',
  Pending: 'Pending'
} as const;

export type StatusValues = typeof STATUS[keyof typeof STATUS];
Enter fullscreen mode Exit fullscreen mode

3. Namespace with Constant Values (types/role.namespace.ts)

Define a namespace for user roles:

export namespace Role {
  export const Admin = 'Admin';
  export const User = 'User';
  export const Guest = 'Guest';
}

export type RoleType = typeof Role.Admin | typeof Role.User | typeof Role.Guest;
Enter fullscreen mode Exit fullscreen mode

4. Class with Static Properties (types/role.class.ts)

Define a class with static properties for user roles:

export class UserRole {
  static readonly Admin = 'Admin';
  static readonly User = 'User';
  static readonly Guest = 'Guest';
}

export type UserRoleType = string;
Enter fullscreen mode Exit fullscreen mode

5. Mapped Type (types/status-values.ts)

Define a mapped type for user statuses:

const StatusValues = {
  Active: 'Active',
  Inactive: 'Inactive',
  Pending: 'Pending'
} as const;

export type MappedStatusType = keyof typeof StatusValues;
Enter fullscreen mode Exit fullscreen mode

Step 3: Implement Components Using Enum Alternatives

Next, let’s set up each component to demonstrate these alternatives.

UserStatusComponent (Union Type and Constant Object)

In user-status.component.ts, import the union type and constant object, and create a method to set the user's status:

import { Component } from '@angular/core';
import { UserRoleType, UserRole } from '../types/role.class';
import { RoleType, Role } from '../types/role.namespace';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-user-role',
  standalone: true,
  imports: [FormsModule],
  templateUrl: './user-role.component.html',
  styleUrl: './user-role.component.scss',
})
export class UserRoleComponent {
  role: RoleType = Role.User;
  userRoles: UserRoleType[] = [UserRole.Admin, UserRole.User, UserRole.Guest];

  setRole(newRole: RoleType) {
    this.role = newRole;
  }
}
Enter fullscreen mode Exit fullscreen mode

In user-status.component.html, use a dropdown to display and select statuses:

<h3>Set User Status</h3>
<select [(ngModel)]="status">
    @for (s of statusValues; track $index) {
    <option [value]="s">{{ s }}</option>
    }
</select>
<p>Current Status: {{ status }}</p>
Enter fullscreen mode Exit fullscreen mode

UserRoleComponent (Namespace and Static Class)

In user-role.component.ts, import the namespace and class-based role definitions:

import { Component } from '@angular/core';
import { UserRoleType, UserRole } from '../types/role.class';
import { RoleType, Role } from '../types/role.namespace';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-user-role',
  standalone: true,
  imports: [FormsModule],
  templateUrl: './user-role.component.html',
  styleUrl: './user-role.component.scss',
})
export class UserRoleComponent {
  role: RoleType = Role.User;
  userRoles: UserRoleType[] = [UserRole.Admin, UserRole.User, UserRole.Guest];

  setRole(newRole: RoleType) {
    this.role = newRole;
  }
}
Enter fullscreen mode Exit fullscreen mode

In user-role.component.html, use a dropdown to select roles:

<h3>Set User Role</h3>
<select [(ngModel)]="role">
    @for (r of userRoles; track $index) {
    <option [value]="r">{{ r }}</option>
    }
</select>
<p>Current Role: {{ role }}</p>
Enter fullscreen mode Exit fullscreen mode

Step 4: Display Components in the App Component

In app.component.html, add both UserStatusComponent and UserRoleComponent to display them on the page:

<h2>User Management</h2>
<app-user-status></app-user-status>
<app-user-role></app-user-role>
Enter fullscreen mode Exit fullscreen mode

Step 5: Configure the Application

Make sure to import the components in app.component.ts:

import { Component } from '@angular/core';
import { UserRoleComponent } from './user-role/user-role.component';
import { UserStatusComponent } from './user-status/user-status.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [UserRoleComponent, UserStatusComponent],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss',
})
export class AppComponent {
  title = 'enum-alternatives-app';
}
Enter fullscreen mode Exit fullscreen mode

In app.config.ts, provide the necessary configuration:

import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)]
};
Enter fullscreen mode Exit fullscreen mode

Step 6: Run the Application

Now, start the Angular development server:

ng serve
Enter fullscreen mode Exit fullscreen mode

Open your browser and navigate to http://localhost:4200 to see the application. You should see dropdowns to select the user status and role, with current selections displayed below each dropdown.

Summary

This Angular app demonstrates how to use various enum alternatives in TypeScript: union types, constant objects, namespaces, classes with static properties, and mapped types. This approach allows for flexibility and type safety when working with a small set of constants and types in Angular.

Feel free to extend this example or customize it further to suit your requirements. Enum alternatives are powerful tools in TypeScript that can help you manage related constants effectively in your Angular applications.

Happy coding! πŸš€


Exploring the Code

Visit the GitHub repository to explore the code in detail.


Top comments (0)