While implementing a simple credential store based on JSON files I ran into a problem where I need to do a seemingly unnecessary roundtrip back to JSON for Dart's oauth2.Credentials.fromJson()
constructor to work.
Background: I am following the oauth2 package's Authorization Code Grant example but with the difference that instead of a single Credentials
object, I want to save a list of Credentials
.
Here is a stripped-down version of my credential store:
import 'dart:convert';
import 'dart:io';
import 'package:oauth2/oauth2.dart';
class CredentialStore {
List<Credentials> get credentials {
// credentials.json would contain a JSON array of objects created with oauth2.Credentials.toJson()
final file = File('credentials.json');
final jsonString = file.readAsStringSync();
final List cred = jsonDecode(jsonString);
return List<Credentials>.from(cred.map((e) => Credentials.fromJson(e)));
}
}
The last line is adapted from this answer and is accepted by the compiler but fails like this on runtime:
Unhandled exception:
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'
The code, however, runs successfully, if I take a round-trip back to JSON when mapping, like so:
return List<Credentials>.from(cred.map((e) => Credentials.fromJson(jsonEncode(e))));
This seems unnecessary and looks bad to me. Is this essentially a problem with the Credentials.fromJson()
implementation in that it cannot accept maps already parsed from JSON or is it possible to rewrite my get credentials
implementation in a way that avoids encoding back to JSON?