1

In an Angular2 application (using Angular 13 and Typescript 4.5.5) we use a lot of string enums like this:

    export enum Language {
       de = "German",
       fr = "French",
       it = "Italian",
       en = "English"
     }

    export class Request {
       language: Language = Language.de;
       ... // other enum-valued properties like the above
     }

The value of the enum (e.g. "Italian") is the value that should be displayed to the user, e.g. in a drop-down. The enum key (e.g. 'it') is what we would like to store in the database when we submit the data to our backend REST service that is implemented in Java.

So in the backend service we have a corresponding Java enum defined as this:

public enum Language {
    de, fr, it, en
}

@Entity
public class Request {
    @Enumerated(EnumType.STRING)
    private Language language;

    ... // other persistent properties
}

The problem is that when the data is submitted to the backend service, the Typescript enum is serialized to JSON using its value. So the service receives "Italian" instead of "it" and cannot map it to the Java enum.

Similarly, when we try to retrieve data from the backend service to display it in the Angular GUI, the service sends "it" instead "Italian", so the deserialization of JSON to the TypeScript enum also fails.

Is there any way to tell TypeScript that it should use the enum key both when serializing and deserializing an enum to/from JSON?

And more generally, which approach would you suggest for what we're trying to achieve (i.e. separate the display value shown to the user from the technical value to be stored in the database)?

mpapado
  • 23
  • 4
  • 1
    https://stackoverflow.com/questions/62215454/how-to-get-enum-key-by-value-in-typescript – Kenneth Oct 04 '22 at 14:38
  • @Kenneth Thanks, but the thread you linked has almost nothing to do with my question. My question is about *serializing* an enum using its *key*. The thread you linked is about retrieving an enum key from its value. – mpapado Oct 04 '22 at 21:19
  • The semantics of the enum are such that each key has a value, and overriding that breaks basic logic. – Kenneth Oct 04 '22 at 21:33
  • I'm not sure which part of my code breaks the rule that "each key has a value". I'm just asking if/how it would be possible to serialize/deserialize an enum to Json using its keys. – mpapado Oct 04 '22 at 22:10
  • By passing `Language.de` into your request, you're specifying a value. I don't know that there's any serialization that happens there, I think you're just giving it a string. – Kenneth Oct 04 '22 at 22:42

1 Answers1

0

I sadly still can't comment but... as a reply now: I'm presuming you are working with either Angular Material or PrimeNG as a GUI.

With both options you have e.g. for a dropdown the ability to set the value you want to display to the user (in your case "Italian") to a different variable than the value you want to have changed /stored (in your case "it").

ex. prime ng: [https://www.primefaces.org/primeng-v11-lts/#/dropdown][1]

<p-dropdown [options]="languages" [(ngModel)]="selectedlanguage" optionLabel="nameFull" optionValue="nameShort"></p-dropdown>

ex angular material: [https://material.angular.io/components/select/overview#getting-and-setting-the-select-value][1]

<mat-select [(ngModel)]="selectedlanguage" name="language">
      <mat-option *ngFor="let language of alllanguages" [value]="language.nameShort">
        {{language.nameLong}}
      </mat-option>
</mat-select>

.js:

interface Languages {
  name: string;
  namelong: string;
}
string selectedlanguage;
Languages alllanguages[] =  // as an with all your values.

Hope this helps :)

Liri22
  • 13
  • 4
  • We are using Angular Material. Thanks a lot for your reply, but it is not clear to me what your model looks like. What is the type of property "allCountries"? Is it an array of Country, where Country is an enum? And if Country is an enum, then where are the properties nameShort and nameLong defined? As far as I know, TypeScript enums cannot have properties, right? It would be really helpful if you could expand your example to show how your model/component is set up. – mpapado Oct 04 '22 at 21:14
  • @mpapado I added the js and updated the names of the variables, maybe it also would help to look at the doku of angular material. – Liri22 Oct 06 '22 at 08:51