Pelajari cara mudah parsing JSON ke Dart class di Flutter. Tutorial ini akan memandu Anda langkah demi langkah untuk mengonversi data JSON menjadi Dart class, sehingga memudahkan pengelolaan data dalam aplikasi Flutter Anda. Cocok untuk pemula dan yang ingin mempercepat proses pengembangan aplikasi di Flutter.
Mengelola data JSON menjadi salah satu bagian penting dalam pengembangan aplikasi, terutama di Flutter. Untuk memudahkan proses ini, saya telah membuat sebuah class bernama Parser yang dirancang khusus untuk menangani parsing JSON ke dalam Dart dengan lebih efisien dan terstruktur. Dalam artikel ini, saya akan membahas bagaimana Parser dapat membantu Anda mengelola data JSON dengan mudah, serta langkah-langkah untuk menerapkannya di proyek Flutter Anda.
import 'dart:convert';
import 'package:get/get.dart';
class Parser {
static String _toCamelCase(String snakeCase) {
return snakeCase.replaceAllMapped(
RegExp(r'_([a-z])'),
(Match match) => match.group(1)!.toUpperCase(),
);
}
static dynamic getFromMap(Map<String, dynamic> map, String key) {
if (map.containsKey(key)) {
return map[key];
} else if (map.containsKey(_toCamelCase(key))) {
return map[_toCamelCase(key)];
}
return null;
}
static T? to<T>(
dynamic value, {
Function(Map<String, dynamic>)? parser,
}) {
String runtimeType = '${(<T>[]).runtimeType}';
if (value == null || value is T) {
return value;
} else if (runtimeType == 'List<List<String>>' ||
runtimeType == 'List<List<String?>>' ||
runtimeType == 'List<List<String>?>') {
return toList<String>(value) as T;
} else if (runtimeType == 'List<List<int>>' ||
runtimeType == 'List<List<int?>>' ||
runtimeType == 'List<List<int>?>') {
return toList<int>(value) as T;
} else if (runtimeType == 'List<List<double>>' ||
runtimeType == 'List<List<double?>>' ||
runtimeType == 'List<List<double>?>') {
return toList<double>(value) as T;
} else if (runtimeType == 'List<List<DateTime>>' ||
runtimeType == 'List<List<DateTime?>>' ||
runtimeType == 'List<List<DateTime>?>') {
return toList<DateTime>(value) as T;
} else if (runtimeType == 'List<List<bool>>' ||
runtimeType == 'List<List<bool?>>' ||
runtimeType == 'List<List<bool>?>') {
return toList<bool>(value) as T;
} else if (runtimeType == 'List<String>' || runtimeType == 'List<String?>' || runtimeType == 'List<String>?') {
return toStringValue(value) as T;
} else if (runtimeType == 'List<int>' || runtimeType == 'List<int?>' || runtimeType == 'List<int>?') {
return toInt(value) as T;
} else if (runtimeType == 'List<double>' || runtimeType == 'List<double?>' || runtimeType == 'List<double>?') {
return toDouble(value) as T;
} else if (runtimeType == 'List<DateTime>' ||
runtimeType == 'List<DateTime?>' ||
runtimeType == 'List<DateTime>?') {
return toDateTime(value) as T;
} else if (runtimeType == 'List<bool>' || runtimeType == 'List<bool?>' || runtimeType == 'List<bool>?') {
return toBool(value) as T;
} else if (runtimeType.contains('List<List<')) {
if (parser != null) {
return toModels(value, parser: parser) as T;
}
} else if (runtimeType.contains('List<')) {
if (parser != null) return toModel<T>(value, parser: parser) as T;
} else {
return value;
}
return null;
}
static num toNum(dynamic value) {
if (value == null) {
return value;
} else if (value is num) {
return value;
} else if (value is String) {
return num.tryParse(value.numericOnly()) ?? 0;
}
return 0;
}
static int? toInt(dynamic value) {
if (value == null) {
return value;
} else if (value is int) {
return value;
} else if (value is double) {
return value.toInt();
} else if (value is String) {
return int.tryParse(value.numericOnly()) ?? double.tryParse(value.numericOnly())?.toInt() ?? 0;
} else {
return 0;
}
}
static double? toDouble(dynamic value) {
if (value == null) {
return value;
} else if (value is double) {
return value;
} else if (value is int) {
return value.toDouble();
} else if (value is String) {
return double.tryParse(value) ?? 0.0;
} else {
return 0.0;
}
}
static DateTime? toDateTime(dynamic value) {
if (value == null) {
return value;
} else if (value is DateTime) {
return value;
} else if (value is String) {
try {
if (value.trim() == '') return null;
return DateTime.parse(value).toLocal();
} catch (_) {
return DateTime(1999, 1, 1).toLocal();
}
} else if (value is int) {
if (value.toString().length <= 10) {
return DateTime.fromMillisecondsSinceEpoch(value * 1000).toLocal();
} else if (value.toString().length <= 13) {
return DateTime.fromMillisecondsSinceEpoch(value).toLocal();
} else if (value.toString().length <= 16) {
return DateTime.fromMicrosecondsSinceEpoch(value).toLocal();
} else {
throw ArgumentError("Invalid timestamp format.");
}
}
// else if (value is Timestamp) {
// return value.toDate().toLocal();
// }
else {
throw ArgumentError("Unsupported input type.");
}
}
static T? toModel<T>(
dynamic value, {
Function(Map<String, dynamic>)? parser,
}) {
if (value is T || value == null || parser == null) {
return value;
} else if (value is String) {
return parser(jsonDecode(value));
} else {
return parser(value);
}
}
static List<T>? toModels<T>(
dynamic value, {
required Function(Map<String, dynamic>) parser,
}) {
if (value is T || value == null) {
return value;
}
var tmp = value is String ? jsonDecode(value) : value;
if (tmp is! List) {
return null;
}
var parsedList = tmp.map<T>((e) {
return parser(e is String ? jsonDecode(e) : e as Map<String, dynamic>);
}).toList();
return parsedList;
}
static bool? toBool(dynamic value) {
if (value == null) {
return value;
} else if (value is bool) {
return value;
} else if (value is int) {
return value != 0;
} else if (value is double) {
return value != 0.0;
} else if (value is String) {
int? tmpInt = int.tryParse(value);
if (tmpInt != null) {
return tmpInt == 1 ? true : false;
}
return value.toLowerCase() == 'true';
} else {
return false;
}
}
static String? toStringValue(dynamic value) {
if (value == null) {
return value;
} else {
return value.toString();
}
}
static List<T> toList<T>(dynamic value) {
if (value is String && value.isNotEmpty) {
value = value.replaceAll(RegExp(r'[{}\[\]]'), '');
value = value.split(',');
}
if (value is List) {
return value.map<T>((e) {
if (e is T) {
return e;
} else if (T == String) {
return toStringValue(e) as T;
} else if (T == int) {
return toInt(e) as T;
} else if (T == double) {
return toDouble(e) as T;
} else if (T == DateTime) {
return toDateTime(e) as T;
} else if (T == bool) {
return toBool(e) as T;
} else {
return e as T;
}
}).toList();
} else {
return [];
}
}
static Map<String, dynamic> toMap(dynamic value) {
if (value is Map<String, dynamic>) {
return value;
} else {
return {};
}
}
static List<int> parseToIntList(dynamic input) {
List<int> result = [];
if (input is List) {
for (var item in input) {
if (item is int) {
result.add(item);
} else if (item is String) {
int? parsedInt = int.tryParse(item);
if (parsedInt != null) {
result.add(parsedInt);
}
}
}
} else if (input is String) {
try {
if (input.startsWith("[") && input.endsWith("]")) {
input = input.substring(1, input.length - 1);
}
List<String> items = input.split(",");
for (var item in items) {
int? parsedInt = int.tryParse(item.trim());
if (parsedInt != null) {
result.add(parsedInt);
}
}
} catch (e) {
throw ("Error parsing input: $e");
}
}
return result;
}
}
Contoh penggunaan secara umum
int? number = Parser.to<int>(map['number_key']);
Contoh penggunaan pada class model
factory AppInfo.fromMap(Map<String, dynamic> map) {
return AppInfo(
appName: Parser.to<String>(map['app_name']),
version: Parser.toModel<Version>(map['version'], parser: Version.fromMap),
maintenance: Parser.toModel<Maintenance>(map['maintenance'], parser: Maintenance.fromMap),
osCompatibility: Parser.toModel<OsCompatibility>(map['os_compatibility'], parser: OsCompatibility.fromMap),
configuration: Parser.toModel<Configuration>(map['configuration'], parser: Configuration.fromMap),
url: Parser.toModel<Url>(map['url'], parser: Url.fromMap),
serverInfo: Parser.toModel<ServerInfo>(map['server_info'], parser: ServerInfo.fromMap),
);
}
Dengan class Parser, proses parsing JSON ke dalam Dart menjadi lebih praktis dan efisien. Saya harap artikel ini bermanfaat untuk Anda yang sedang membangun aplikasi Flutter dan ingin meningkatkan produktivitas dalam mengelola data JSON. Jangan ragu untuk mencoba, dan jika ada pertanyaan atau masukan, saya akan sangat senang mendiskusikannya di kolom komentar. Selamat coding!
Your email address will not be published. Required fields are marked *