What's the most effective method for adding fields to an enum in Angular, similar to Swift or Kotlin?

Coming from the world of mobile development, I am currently delving into Angular for a new project.

I find it quite convenient to add fields to an enum in languages like Swift or Kotlin. For instance, in Swift:

enum Status: Int {
  case connected = 0, disconnected = 1

  var title: String {
      switch self {
        case .connected:
            return "Connected"
        case .disconnected:
            return "Disconnected"
      }
  }

  var color: UIColor {
    switch self {
      case .connected:
        return .green
      case .disconnected:
        return .red
    }
  }

}

Usage example:

let status = Status.connected
print(status.title) // Output Connected
print(status.color) // Output green

In TypeScript, when attempting to achieve similar functionality, I found two potential methods: Pipe and namespace.

My implementation using the pipe method:

export enum Status {
  connected = 0, disconnected = 1
}

@Pipe({name: 'color'})
export class StatusColor implements PipeTransform {

  transform(value: Status): string {
    switch (value) {
      case Status.connected:
        return 'green';
      case Status.disconnected:
        return 'red';
    }
  }

}

@Pipe({name: 'title'})
export class StatusTitle implements PipeTransform {

  transform(value: Status): string {
    switch (value) {
      case Status.connected:
        return 'Connected';
      case Status.disconnected:
        return 'Disconnected';
    }
  }

}

Implementation in HTML:

user.status | color
user.status | title

While this approach provides a visually appealing code in the HTML usage, the drawback is having to create a custom pipe for each field and declare it in the app.module. With numerous enums, it can result in redundant code and declarations. Is this still considered good practice?

My alternate solution using the namespace method:

export enum Status {
    connected = 0, disconnected = 1
}

export namespace Status {

  export function titleOf(state: Status): string {
    switch (state) {
      case Status.disconnected:
        return 'Disconnected';
      case Status.connected:
        return 'Connected';
    }
  }

  export function colorOf(state: State): string {
    switch (state) {
      case Status.disconnected:
        return 'red';
      case Status.connected:
        return 'green';
    }
  }

}

Usage in HTML:

Status.titleOf(user.status)
Status.colorOf(user.status)

This second approach is more straightforward but lacks the elegance of the first method.

So, what would be the recommended approach for achieving this requirement? Is there a better way to streamline the code by creating a single pipe with sub-names for each transformation?

Answer №1

Utilizing pipes is a step in the right direction for your solution.

To avoid creating multiple custom pipes for different variations, consider adding an argument to the pipe using guidance from the Angular documentation linked here. It may be beneficial to define an enum to specify the parameter and prevent any ambiguous string values:

enum StyleType {
  title = 'title',
  color = 'color'
}

In the pipe implementation, utilize a switch statement based on the StyleType enum to return the desired output.

An added benefit of using pipes is that if the input remains constant, the pipe will consistently provide the same output without unnecessary computations, leading to potential performance gains (source).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When I attempt to return an object from a function and pass the reference to a prop, TypeScript throws an error. However, the error does not occur if the object is directly placed in

Currently, I have the following code block: const getDataForChart = () => { const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; const test = { ...

In Typescript Angular, how can I invoke a function on each element of an array as part of a sequence of Observables, and then return the total number of successful operations?

I am faced with the task of creating a parent record followed by multiple child records (order does not matter), and ending with a logging action. I am knowledgeable on how to chain single actions on an observable by mapping them together. For example: - ...

How to make a div stand out when clicked in an Angular application

Within my code, there is a booking-list div that I am utilizing to showcase booking timings. When hovering over this div, the background-color changes, as depicted in the image below. https://i.stack.imgur.com/Iz1r6.png My current dilemma is that when se ...

`On the first date chosen, activate an event within the ngx-bootstrap daterangepicker.`

I am utilizing a date range picker with the following code: <bs-daterangepicker-inline [bsValue]='bsValue' (bsValueChange)="test()"></bs-daterangepicker-inline>. Is there a way to trigger an event when the first date is sel ...

How can you initialize a JavaScript class that has a member variable of its own class?

I've come across an interesting puzzle. I am creating a class that can dynamically replicate itself to different levels, similar to an expandable menu. The initial definition looks like this: class MyClass { name: string = ''; fields ...

Encountering error E418 when attempting to set up fontawesome with angular cli 6.0.5 installation

Upon running the command 'npm install --save @fortawesome/fontawesome-free-regular' on my Windows machine, I encountered error code E418 - I'm a teapot: @fortawesome-free-regular@latest. Environment: Angular CLI: 6.0.5, Node: 8.9.1, OS: wi ...

Achieving webpack bundling for node_modules in Angular 1: A step-by-step guide

I am facing a challenge as I transition my angular 1 + typescript project build setup from gulp to webpack. The issue lies in bundling the node_modules js files in the correct sequence. Previously, I relied on bower for client-side dependencies, and the u ...

Angular 4 project utilizing the Bootstrap framework

How can I utilize Bootstrap classes like nav-component and the data-toggle attribute in my Angular 4&5 project components within VS Code? After encountering issues with Bootstrap v3, I decided to upgrade to v4.1.7. Although I have linked the source file i ...

What is the best way to retrieve two fields from a selected material select input?

I have a dropdown menu that populates a list of companies. Currently, I am only able to retrieve either the ID or the name of the company from the selection. I need to save both the ID and name of the selected company in my Firestore collection. I attempt ...

What are the benefits of maintaining a property as non-observable instead of observable in knockout.js?

In my TypeScript project utilizing Knockout.js, I have a class with several properties. One of these properties is 'description', which is not directly tied to the DOM but needs to be used in popups triggered by certain mouse events (such as butt ...

Error TS2322 occurs during compilation in Typescript when using ng.IPromise

Having some issues while using Angular 1.x with Typescript. Here is the code causing trouble: get(id): ng.IPromise<Server.MyItem> { return this.$http.get(`${this.baseAddress}/${id}`).then(d => d.data); } After compiling with tsc, I am encoun ...

HammerJS swipe functionality does not seem to be functioning properly on elements that have the overflow CSS

UPDATE: The code snippet works smoothly when embedded in the question, but encounters issues when edited. This led me to discover that the problem lies with underlying containers that require scrolling... After testing it on my phone, I found that Hammer f ...

Tips for dynamically importing parent services

Is it possible to dynamically import service-A (85KB) into service-B (15KB) and then dynamically import service-B into app.comp.ts when needed? Check out the Stackblitz Demo here View the FlowChart here ...

Exploring techniques for looping through JSON response data in Angular 2 using TypeScript

When I receive this JSON data as a response, I attempt to iterate through it inside the "component template attribute" in order to display the content within an "li" tag HTML. { "items": [ { "aliases": [ "http://www.xyz.co", ...

Unusual TypeScript Syntax

While examining a TypeScript function designed to calculate average run time, I stumbled upon some unfamiliar syntax: func averageRuntimeInSeconds(runs []Run) float64 { var totalTime int var failedRuns int for _, run := range runs { ...

attempting to pass a boolean type through props resulting in a type error

Hey, check out this component I created: import * as Styled from './styles'; export type HeadingProps = { children: React.ReactNode | string; colorDark: boolean; }; export const Heading = ({ children, colorDark }: HeadingProps) => { re ...

TS2345 Error: Cannot assign type 'string | null' to type 'number' for the parameter

Encountered an error while compiling and running the code in my Angular application: Error TS2345: Argument of type 'string | null' cannot be assigned to a parameter of type 'number'. Type 'null' is not assignable to type &ap ...

The PrimeNg confirmDialog is updating my navbar with some modifications

Despite my navbar working well and being fully responsive, I encountered an issue where opening a confirm dialog in the background caused the navbar width to expand to 800px even though the screen width was 1480px, creating empty space on the right side, a ...

Combining JSON data in Typescript using the merge method

Is there a way to effectively merge JSON objects in such a manner that simple values (strings, numbers, booleans, etc) get overridden when keys match, but when dealing with complex values (arrays and objects), different outcomes apply? 1.) For simple array ...

Understanding a compound data type in TypeScript

Hey there, I'm new to TypeScript and I'm facing a challenge in defining the type for an object that might have the following structure at runtime: { "animals" : [ { name: "kittie", color: "blue" }, { name: ...