RVP
RVP

Reputation: 2400

Angular2 and TypeScript enums - dos and don'ts

I have a bunch of enums in my Angular2 app and for each enum I've created a corresponding utils class that provides some additional functionality. This simply goes around the TypeScript limitation that I can't add functions to an enum the same way I can do it in Java.

Here's an example of my country enum and the corresponding utils class:

import {Injectable} from "@angular/core";

export enum Country {
    ANDORRA = <any>"ANDORRA",
    UNITED_ARAB_EMIRATES = <any>"UNITED_ARAB_EMIRATES",
    AFGHANISTAN = <any>"AFGHANISTAN",
    // ...
    // more countries skipped for brevity 
    // ...
    ZAMBIA = <any>"ZAMBIA",
    ZIMBABWE = <any>"ZIMBABWE"
}


@Injectable()
export class CountryUtils {

    private _emptyEntry: Array<string> = ["", "", ""];

    private countryData: any = {
        ANDORRA: ["Andorra", "AD", "AND"],
        UNITED_ARAB_EMIRATES: ["United Arab Emirates", "AE", "ARE"],
        AFGHANISTAN: ["Afghanistan", "AF", "AFG"],
        // ...
        // more countries skipped for brevity
        // ...
        ZAMBIA: ["Zambia", "ZM", "ZMB"],
        ZIMBABWE: ["Zimbabwe", "ZW", "ZWE"]
    }

    getData(country: Country): any {
        if (!country) {
            return this._emptyEntry;
        }
        return this.countryData[Country[country]];
    }

    getName(country: Country): any {
        return this.getData(country)[0];
    }

    getCode2(country: Country): any {
        return this.getData(country)[1];
    }

    getCode3(country: Country): any {
        return this.getData(country)[2];
    }
}

Now, as you can see I've marked the utils class as Injectable so that I can use it with DI where I need it.

The problem I'm facing is that these enums are also used in my core TS/JS model classes that are not Angular2 dependent so I can't use DI to inject an instance of my utils classes (like the one above) inside the core model classes.

The only work around that I see is to drop the Injectable() approach and to mark the methods in the utils classes as static. So this way I can just import each utils class together with the enum and use it anywhere I want.

My question is, how bad of a design decision would that be? Is it acceptable to do something like this in Angular2 or is using statics a complete no-no? I can't see anything particularly harmful other that it's like an eye sore compared to the regular DI approach.

Any advice would be very much appreciated. Thanks in advance!

Upvotes: 1

Views: 1070

Answers (1)

Rodris
Rodris

Reputation: 2858

I don't see a static class as a problem. Also, you can use Declaration Merging to add your util functionality to your enum. No need of extra class. Check below.

enum Country {
    ANDORRA = <any>"ANDORRA",
    UNITED_ARAB_EMIRATES = <any>"UNITED_ARAB_EMIRATES",
    AFGHANISTAN = <any>"AFGHANISTAN",
    // ...
    // more countries skipped for brevity 
    // ...
    ZAMBIA = <any>"ZAMBIA",
    ZIMBABWE = <any>"ZIMBABWE"
}

namespace Country {

    const _emptyEntry: Array<string> = ["", "", ""];

    const countryData: any = {
        ANDORRA: ["Andorra", "AD", "AND"],
        UNITED_ARAB_EMIRATES: ["United Arab Emirates", "AE", "ARE"],
        AFGHANISTAN: ["Afghanistan", "AF", "AFG"],
        // ...
        // more countries skipped for brevity
        // ...
        ZAMBIA: ["Zambia", "ZM", "ZMB"],
        ZIMBABWE: ["Zimbabwe", "ZW", "ZWE"]
    };

    export function getData(country: Country): any {
        if (!country) {
            return this._emptyEntry;
        }
        return this.countryData[Country[country]];
    }

    export function getName(country: Country): any {
        return this.getData(country)[0];
    }

    export function getCode2(country: Country): any {
        return this.getData(country)[1];
    }

    export function getCode3(country: Country): any {
        return this.getData(country)[2];
    }
}

Country.getCode2(Country.AFGHANISTAN);

Upvotes: 1

Related Questions