Posted by Kosal
Get and Set your nested Map without converting them to a model mapped version. Just use the key path to go directly where you want and get, set keys and values.
Get value from a Map by path. Use dot notation in [path] to access nessted keys. If location of path doesn't exist, it will return defaultValue.
T? mapGetter<T>(Map map, String path, T defaultValue) {
List<String> keys = path.split('.');
String key = keys[0];
if (!map.containsKey(key)) {
return defaultValue;
}
if (keys.length == 1) {
return map[key] as T;
}
return mapGetter(map[keys.removeAt(0)], keys.join('.'), defaultValue);
}
Map<String, dynamic> a = {
'a': {
'b': {
'c': {
'd': 'This is d',
},
}
}
};
Map<String, dynamic>? c = mapGetter<Map<String, dynamic>>(a, 'a.b.c', {});
String? d = mapGetter(a, 'a.b.c.d', 'no value');
String? e = mapGetter(a, 'a.b.c.e', 'no value');
print(c);
print(d);
print(e);
{d: This is d}
This is d
no value
Sets value to the Map by path. If location of path doesn't exist, it will created.
Map<String, dynamic> mapSetter<T>(
Map<String, dynamic>? map,
String path,
T value,
) {
List<String> keys = path.split('.');
String key = keys[0];
Map<String, dynamic> target = map ?? {};
if (keys.length == 1) {
return Map<String, dynamic>.from({
...target,
key: value,
});
}
return Map<String, dynamic>.from({
...target,
key: mapSetter(target[keys.removeAt(0)] ?? {}, keys.join('.'), value),
});
}
Map<String, dynamic> a = {
'a': {
'b': {
'c': {
'd': 'This is d',
},
}
}
};
Map<String, dynamic> d = mapSetter(a, 'a.b.c.d', 'This is d modified');
Map<String, dynamic> e = mapSetter(d, 'a.b.c.e', 'This is e');
print(d);
print(e);
{a: {b: {c: {d: This is d modified}}}}
{a: {b: {c: {d: This is d modified, e: This is e}}}}