get<T> method
Reads an attribute, resolving a dotted path into the nested objects the server builds from a card's relation field. A null anywhere along the path, or a type mismatch, yields null rather than throwing.
Implementation
T? get<T>(String path) {
// A literal key first, before treating the dots as a traversal.
//
// The record endpoint writes FORM paths flat: a translatable field is
// published as `caption.en` and Laravel validates it as a path, but an
// infolist entry named `caption` is Spatie's accessor — the current
// locale's string. They are different things sharing one base key, so the
// server keeps them apart and the client must read them apart. Traversing
// first would find the infolist's nested value and answer the wrong
// question, or find nothing and blank a prefilled edit form.
//
// `FormValues._readPath` has had this rule since the form path was built;
// this gives the record the same one.
if (attributes.containsKey(path)) {
final literal = attributes[path];
return literal is T ? literal : null;
}
dynamic value = attributes;
for (final segment in path.split('.')) {
if (value is! Map<String, dynamic>) return null;
value = value[segment];
if (value == null) return null;
}
return value is T ? value : null;
}