tryFromJson static method
Attempts to parse a UserModel from an API response map.
Validates the structure of json using JsonSentinel.validate
before parsing. Returns null if validation fails or any field
conversion throws, making this safe to call on untrusted API data.
Date-time fields (email_verified_at, created_at, updated_at) are
parsed with DateTime.parse; a parse failure for any individual field
sets that field to null rather than aborting the whole parse.
Returns the parsed UserModel, or null on any failure.
Implementation
static UserModel? tryFromJson(Map<String, dynamic> json) {
final Map<String, List<Type?>?> expectedTypes = <String, List<Type?>?>{
"id": <Type?>[int],
"first_name": <Type?>[String],
"last_name": <Type?>[String],
"email": <Type?>[String],
"notifications_enabled": <Type?>[bool],
"profile_image_url": <Type?>[null, String],
"email_verified_at": <Type?>[null, String],
"created_at": <Type?>[null, String],
"updated_at": <Type?>[null, String],
};
final bool ok = JsonSentinel.validate(json: json, expectedTypes: expectedTypes, context: 'UserModel', escalate: true).isValid;
if (!ok) return null;
try {
final int id = json["id"] as int;
final String firstName = json["first_name"] as String;
final String lastName = json["last_name"] as String;
final String email = json["email"] as String;
final bool isNotificationsEnabled = json["notifications_enabled"] as bool;
final String? profileImageUrl = json["profile_image_url"] as String?;
final String? emailVerifiedAtRaw = json["email_verified_at"] as String?;
final String? createdAtRaw = json["created_at"] as String?;
final String? updatedAtRaw = json["updated_at"] as String?;
DateTime? parseNullableDateTime(String? value, String field) {
if (value == null) return null;
try {
return DateTime.parse(value);
} catch (e, st) {
JsonSentinel.logger?.call(
'[UserModel] Failed to parse DateTime field.',
error: e,
stackTrace: st,
extras: <String, Object?>{'field': field, 'value': value},
escalate: false,
);
return null;
}
}
return UserModel(
id: id,
firstName: firstName,
lastName: lastName,
email: email,
isNotificationsEnabled: isNotificationsEnabled,
profileImageUrl: profileImageUrl,
emailVerifiedAt: parseNullableDateTime(emailVerifiedAtRaw, 'email_verified_at'),
createdAt: parseNullableDateTime(createdAtRaw, 'created_at'),
updatedAt: parseNullableDateTime(updatedAtRaw, 'updated_at'),
);
} catch (e, st) {
JsonSentinel.logger?.call(
'[UserModel] Parsing failed after validation (skipping user).',
error: e,
stackTrace: st,
extras: const <String, Object?>{'model': 'UserModel'},
escalate: true,
);
return null;
}
}