Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to serialize/deserialize Dart's new enum with JSON?

Tags:

json

enums

dart

I'd like to make use of Dart's new (experimental) enum feature instead of using stacks of static const Strings, but what's the best way to serialize/deserialize enum variables using JSON? I've made it work this way, but surely there's a better solution:

enum Status {
  none,
  running,
  stopped,
  paused
}

Status status1 = Status.stopped;
Status status2 = Status.none;

String json = JSON.encode(status1.index);
print(json);   // prints 2

int index = JSON.decode(json);
status2 = Status.values[index];
print(status2);  // prints Status.stopped

If you serialize using the index, you can get locked into keeping your enums in the same order forever, so I'd much prefer to use some kind of String form. Anyone figured this out?

like image 889
montyr75 Avatar asked Dec 01 '14 20:12

montyr75


People also ask

How do you serialize an enum?

To serialize an enum constant, ObjectOutputStream writes the value returned by the enum constant's name method. To deserialize an enum constant, ObjectInputStream reads the constant name from the stream; the deserialized constant is then obtained by calling the java.

How do you deserialize an enum in Java?

The @JsonValue annotation is one of the annotations which we can use for both serializing and deserializing enums. Enum values are constants, and due to this, @JsonValue annotation can be used for both. First we simply add the getter method to our Distance. java by using the @JsonValue annotation.

How do I pass enum as JSON?

All you have to do is create a static method annotated with @JsonCreator in your enum. This should accept a parameter (the enum value) and return the corresponding enum. This method overrides the default mapping of Enum name to a json attribute .

How is enum represented in JSON?

JSON has no enum type. The two ways of modeling an enum would be: An array, as you have currently. The array values are the elements, and the element identifiers would be represented by the array indexes of the values.

How do I deserialize an enum in Jackson?

Default Behavior By default, Jackson will use the Enum name to deserialize from JSON. For example, it will deserialize the JSON: 4.2. Using @JsonValue We've learned how to use @JsonValue to serialize Enums.

How do I deserialize a JSON object in Jackson?

Default Behavior By default, Jackson will use the Enum name to deserialize from JSON. For example, it will deserialize the JSON: 4.2. Using @JsonValue

How can I serialize enum names in JSON?

You can serialize enum names as strings. By default, fields are ignored. You can include fields. By default, comments or trailing commas in the JSON throw exceptions. You can allow comments and trailing commas. The default maximum depth is 64. When you use System.Text.Json indirectly in an ASP.NET Core app, some default behaviors are different.

How to deserialize JSON data from streamreader to a class?

StreamReader streamReader = new StreamReader (stream); // Output JSON data to console. Console.WriteLine (streamReader.ReadToEnd ()); Deserialize JSON to a Class. To deserialize Json I will create a text file called Person.json containing the correct formatting:


1 Answers

As one of the answer previously suggested, if you share the same implementation on the client and server, then serializing the name is I think the best way and respects the open/closed principle in the S.O.L.I.D design, stating that:

"software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"

Using the index instead of the name would mess up all the logic of your code if you ever need to add another member to the Enum. However using the name would allow extension.

Bottom line, serialize the name of your enum and in order to deserialize it properly, write a little function that given an Enum as a String, iterates over all the members of the Enum and returns the appropriate one. Such as:

Status getStatusFromString(String statusAsString) {
  for (Status element in Status.values) {
     if (element.toString() == statusAsString) {
        return element;
     }
  }
  return null;
}

So, to serialize:

Status status1 = Status.stopped;
String json = JSON.encode(status1.toString());
print(json) // prints {"Status.stopped"}

And to deserialize:

String statusAsString = JSON.decode(json);
Status deserializedStatus = getStatusFromString(statusAsString);
print(deserializedStatus) // prints Status.stopped

This is the best way I've found so far. Hope this helps !

like image 105
Pierre Roudaut Avatar answered Sep 20 '22 12:09

Pierre Roudaut