arrayNode<T> method
JsonArray<List<T> >
arrayNode<T>(})
Throws SquintException if key is not found.
Implementation
JsonArray<List<T>> arrayNode<T>(
String key, {
T Function(JsonObject)? decodeFromJsonObject,
Function? decoder,
List? childType,
}) {
final dynamicData = byKey(key).data as List;
final expectedChildType = T.toString();
final actualChildType = dynamicData.runtimeType
.toString()
.removePrefixIfPresent("List<")
.removePostfixIfPresent(">");
// Types match so cast and return List<T>.
if (expectedChildType == actualChildType) {
return JsonArray<List<T>>(
key: key,
data: dynamicData.cast<T>().toList(),
);
}
// Use decoder to convert to expected child Type
// and return as List<T>.
if (decodeFromJsonObject != null) {
final objects = dynamicData.map<JsonObject>((dynamic e) {
if (e is Map) {
if (e.values.isNotEmpty && e.values.first is JsonNode) {
return JsonObject(data: e as Map<String, JsonNode>);
} else {
return JsonObject.fromMap(data: e as Map<String, dynamic>);
}
} else {
throw SquintException(
"Expected Map type but found: ${e.runtimeType}");
}
}).toList();
return JsonArray<List<T>>(
key: key,
data: objects.map(decodeFromJsonObject).toList().cast<T>().toList(),
);
}
var depth = 0;
var nextChild = actualChildType;
while (nextChild.startsWith("List<")) {
nextChild =
nextChild.removePrefixIfPresent("List<").removePostfixIfPresent(">");
depth += 1;
}
final isMapType = mapRegex.firstMatch(nextChild);
if (isMapType != null) {
if (depth == 0) {
final objects = dynamicData.map<JsonObject>((dynamic e) {
if (e is Map) {
if (e.values.isNotEmpty && e.values.first is JsonNode) {
return JsonObject(data: e as Map<String, JsonNode>);
} else {
return JsonObject.fromMap(data: e as Map<String, dynamic>);
}
} else {
throw SquintException(
"Expected Map type but found: ${e.runtimeType}");
}
}).toList();
final maps = objects.map<dynamic>((e) {
final type = e.valuesAllOfSameType;
if (type is StringType) {
final stringMap = <String, String>{};
e.data.forEach((key, value) {
stringMap[key] = value.data as String;
});
return stringMap;
} else if (type is IntType) {
final intMap = <String, int>{};
e.data.forEach((key, value) {
intMap[key] = value.data as int;
});
return intMap;
} else if (type is DoubleType) {
final doubleMap = <String, double>{};
e.data.forEach((key, value) {
doubleMap[key] = value.data as double;
});
return doubleMap;
} else if (type is BooleanType) {
final boolMap = <String, bool>{};
e.data.forEach((key, value) {
boolMap[key] = value.data as bool;
});
return boolMap;
} else {
if (decoder != null) {
try {
return decoder.call(e);
} catch (e) {
"Tried to decode data with $decoder but failed."
.log(context: e);
}
}
return e.data;
}
}).toList();
return JsonArray<List<T>>(
key: key,
data: maps.toList().cast<T>().toList(),
);
}
}
final nodes = dynamicData.decodeList;
final decoded = <String, JsonNode>{};
if (decoder != null) {
try {
nodes.forEach((key, value) {
decoded[key] = CustomJsonNode(data: decoder.call(value));
});
} catch (e) {
"Decoding failed due to:".log(context: e);
throw SquintException("Tried to decode data with $decoder but failed.");
}
}
if (decoded.isNotEmpty) {
final decodedList = decoded.toList(valueList: childType);
return JsonArray<List<T>>(
key: key,
data: decodedList.cast<T>(),
);
}
// Return as List with child T.
return JsonArray<List<T>>(
key: key,
data: nodes.toList().cast<T>().toList(),
);
}