A powerful Dart package that extends Map<String, dynamic> with strongly typed
getters and utilities for working with flat and nested JSON data structures.
All package's functionality is built around an extension on the below typedef, making it seamless to be integrated with existing code and allow working with JSON structures with ease.
typedef Json = Map<String, dynamic>;Add superjson to your pubspec.yaml:
dependencies:
superjson: ^1.0.3Then import it in your Dart code:
import 'package:superjson/superjson.dart';final data = {
'name': 'John Doe',
'age': '25', // String that can be parsed as int
'metrics'{
'score': 95.7
},
'settings': {
'active': 'true',
'flag': false
}
};
// Get values with automatic type conversion and defaults
String name = data.getString('name', orElse: 'Unknown'); // 'John Doe'
int age = data.getInt('age'); // 25 (parsed from string)
double score = data.getDouble('metrics.score'); // 95.7
double scoreInt = data.getInt('metrics.score',
roundFn: (v) => v.round()); // 96
bool active = data.getBool('settings.active'); // true
bool flag = data.getBool('settings.flag', orElse: true); // false
// Get values via the generic getter
String name = data.getValue<String>('name'); // 'John Doe'
Json metrics = data.getValue<Json>('metrics'); // {'score': 95.7}
double score = data.getValue<double>('metrics.score'); // 95.7final data = {'email': 'user@example.com'};
// Equivalent to:
// Json data = {'email': 'user@example.com'};
// and:
// Map<String, dynamic> data = {'email': 'user@example.com'};
String? email = data.getStringOrNull('email'); // 'user@example.com'
String? phone = data.getStringOrNull('phone'); // null
int? missing = data.getIntOrNull('missing', orElse: 100); // 100 (custom default)final data = {
'created': '2024-01-15T10:30:00Z',
'updated': 'Mon, 15 Jan 2024 10:30:00 GMT',
};
DateTime created = data.getDateTime('created', DateTime.now());
DateTime? updated = data.getDateTimeOrNull('updated');final data = {
'tags': ['dart', 'json', 'parser'],
'metadata': {'version': '1.0', 'author': 'Example'},
};
List<String> tags = data.getList<String>('tags', []);
Json metadata = data.getJson('metadata', {});final nested = {
'user': {
'name': 'John',
'address': {
'city': 'New York',
}
}
};
// Flatten nested structure
final flat = nested.flattened;
// {'user.name': 'John', 'user.address.city': 'New York'}
// Unflatten back to nested structure
final original = flat.unflattened;
// {'user': {'name': 'John', 'address': {'city': 'New York'}}}class User with Jsonable {
final String name;
final int age;
User(this.name, this.age);
@override
Json toJson() => {'name': name, 'age': age};
}
User user = User('Alice', 30);
Json json = user.toJson(); // {'name': 'Alice', 'age': 30}For more detailed examples, see the /example folder.
The package supports fetching the following types from JSON structures (see below for examples):
- T (Generic)
- Methods:
getValue<T>(),getValueOrNull<T>() - Extracts values of any type
Tdirectly from the JSON structure - Works with all supported types (String, int, double, bool, Duration, DateTime, List, Json, Jsonable, Map<T, V>)
- Supports nested field access via dot notation (e.g.,
"user.profile.name")
- Methods:
All methods support nested field access via dot notation, e.g. myjson.getString('user.profile.name'), myjson.getJson('user.profile'), myjson.getInt('metrics.performance.score') etc.
-
String
- Methods:
getString(),getStringOrNull() - Can also convert from:
num:15➡"15"bool:true➡"true"
- Methods:
-
int
- Methods:
getInt(),getIntOrNull() - Can also convert from:
String(with parsing):"15"➡15,num(with optional rounding):15.0➡15
- Methods:
-
double
- Methods:
getDouble(),getDoubleOrNull() - Can also convert from:
int/num:100➡100.0String(with parsing):"100.5"➡100.5
- Methods:
-
bool
- Methods:
getBool(),getBoolOrNull() - Can also convert from:
String("true"or"false", or additionally '1'/'0'/'yes'/'no' if strict mode is disabled),int(1 = true, 0 = false)
- Supports strict and non-strict parsing modes (pass
strict: true/falseto the getter method)
- Methods:
-
Duration
- Methods:
getDuration(),getDurationOrNull() - Converts from:
int(milliseconds)String(parsed as milliseconds)
- Methods:
-
DateTime
- Methods:
getDateTime(),getDateTimeOrNull() - Converts from:
String(ISO 8601, RFC 2822, RFC 1123 and custom formats)Map(Google's protobuf Timestamp format:{seconds: x, nanos: y})
- Methods:
-
List
- Methods:
getList<T>(),getListOrNull<T>() - Converts from:
Iterable(filters by typeT)
- Methods:
-
Json (Map<String, dynamic>):
- Methods:
getJson() - Converts from:
Map
- Methods:
-
Map<T, V>
- Methods:
getMap<T, V>() - Converts from:
Map
- Methods:
The package provides useful methods to flatten nested JSON structures into dot-notation keys and unflatten them back:
-
flattened getter
- Converts nested JSON structures into a flat map with dot-separated keys
- Example:
{'user': {'name': 'John'}}➡{'user.name': 'John'} - Recursively processes all nested
Jsonobjects andJsonizablemixins
-
unflattened getter
- Reconstructs the original nested structure from a flattened JSON
- Example:
{'user.name': 'John'}➡{'user': {'name': 'John'}} - Automatically groups keys by their prefixes
-
unflatten(prefix) method
- Extracts a subset of keys matching a specific prefix
- Returns a new
Jsonobject with the prefix removed from keys - Useful for isolating specific sections of a flattened structure
The Jsonable mixin provides a standard interface for converting custom Dart objects to JSON structures. Any class that
uses this mixin must implement the toJson() method, which returns a Json (Map<String, dynamic>) representation of
the object.
When the specified key is missing from the JSON structure, the non-nullable get methods return a default value, according to the table below.
| Method | Default Value |
|---|---|
getString() |
'' |
getInt() |
0 |
getDouble() |
0.0 |
getBool() |
false |
getDateTime() |
DateTime.fromMillisecondsSinceEpoch(0) |
getTimestamp() |
DateTime.fromMillisecondsSinceEpoch(0) |
getDuration() |
Duration() |
getList<T>() |
[] |
getJson() |
{} |
getMap<T, V>() |
{} |
Please file feature requests and bugs at the issue tracker.
Licensed under the BSD-3-Clause License.