chongman
chongman

Reputation: 2507

jsonEncode doesn't work with enum extensions; is there a workaround?

In Dart (2.15.0), I'm trying to use jsonEncode with enums by defining a toJson method. And it's not working.

import 'dart:convert';

enum Day { monday, tuesday }

extension ParseToJsonString on Day {
  String toJson() {
    return this.toString().split('.').last;
  }
}

class Saturday {
  String toJson() => "WOOHOO Saturday";
}

main() {
  //works!
  Saturday s=Saturday();
  print(s.toJson());
  print(jsonEncode(s));
  
  Day m = Day.monday;
  print(m.toJson()); //prints 'monday'
  print(m); //prints Day.monday
  print(jsonEncode(m)); // Uncaught Error: Converting object to an encodable object failed: Instance of 'Day'
}

According to the docs, jsonEncode will look for the toJson() method.

And the extensions work when called directly on an enum, but somehow jsonEncode isn't finding the toJSON.

Dart How to get the "value" of an enum https://dart.dev/guides/language/extension-methods

Any idea if this is a bug or the expected behavior?

Otherwise, can I use enums and somehow define something to work with jsonEncode?

Thanks!

Upvotes: 0

Views: 176

Answers (1)

chongman
chongman

Reputation: 2507

I did some digging, and this is the correct behavior due to how jsonEncode works.

See https://github.com/dart-lang/sdk/issues/42742

Note, even using the optional parameter for jsonEncode doesn't fix it:

  print(jsonEncode(m, toEncodable: (x)=>x!.toJson()) ); // won't work.

To get past the "extensions don't work on dynamic types", we have to use a recast as well:

  print(jsonEncode(
    m,
    toEncodable: (x) {
      Day recastX = x as Day;
      return recastX.toJson();
    },
  )); // works, prints 'monday'

See it on dartpad

Upvotes: 1

Related Questions