[FIX] Node initialization logic for non-dynamic values.
This commit is contained in:
@@ -74,38 +74,37 @@ class AstromicFormController {
|
|||||||
if (_nodes.containsKey(id)) {
|
if (_nodes.containsKey(id)) {
|
||||||
final existingNode = _nodes[id]!;
|
final existingNode = _nodes[id]!;
|
||||||
|
|
||||||
// Check if the existing node is already the correct type
|
|
||||||
if (existingNode is AstromicFieldNode<T>) {
|
if (existingNode is AstromicFieldNode<T>) {
|
||||||
return existingNode;
|
return existingNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's a type mismatch (likely <dynamic>), we must migrate it.
|
// Determine a safe value for the replacement node
|
||||||
// We create a new node of the correct type using the existing value.
|
T? migratedValue;
|
||||||
|
|
||||||
|
// 1. Try to cast existing value, but handle nulls
|
||||||
|
if (existingNode.value != null) {
|
||||||
|
migratedValue = existingNode.value as T;
|
||||||
|
} else {
|
||||||
|
// 2. Fallback to initialValue or type-specific defaults
|
||||||
|
migratedValue = initialValue ?? _getDefaultValueForType<T>();
|
||||||
|
}
|
||||||
|
|
||||||
final replacementNode = AstromicFieldNode<T>(
|
final replacementNode = AstromicFieldNode<T>(
|
||||||
existingNode.value as T,
|
migratedValue as T, // Should be safe now
|
||||||
formatter: (v) => v?.toString() ?? '',
|
formatter: (v) => v?.toString() ?? '',
|
||||||
parser: (v) => (T == String ? v : null) as T?,
|
parser: (v) => (T == String ? v : null) as T?,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Transfer validators if they exist
|
|
||||||
replacementNode.validators = existingNode.validators;
|
replacementNode.validators = existingNode.validators;
|
||||||
|
|
||||||
_nodes[id] = replacementNode;
|
_nodes[id] = replacementNode;
|
||||||
return replacementNode;
|
return replacementNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback for new nodes (keep your existing lazy-init logic here)
|
// Fallback for brand-new nodes
|
||||||
T? defaultValue = initialValue;
|
final T startValue = initialValue ?? _getDefaultValueForType<T>() as T;
|
||||||
if (defaultValue == null) {
|
|
||||||
if (T == String)
|
|
||||||
defaultValue = '' as T;
|
|
||||||
else if (T == bool)
|
|
||||||
defaultValue = false as T;
|
|
||||||
else if (T == int) defaultValue = 0 as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
final newNode = AstromicFieldNode<T>(
|
final newNode = AstromicFieldNode<T>(
|
||||||
defaultValue as T,
|
startValue,
|
||||||
formatter: (v) => v?.toString() ?? '',
|
formatter: (v) => v?.toString() ?? '',
|
||||||
parser: (v) => (T == String ? v : null) as T?,
|
parser: (v) => (T == String ? v : null) as T?,
|
||||||
);
|
);
|
||||||
@@ -114,7 +113,13 @@ class AstromicFormController {
|
|||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type _typeOf<T>() => T;
|
/// Helper to ensure we never pass a null to a non-nullable Node constructor
|
||||||
|
T? _getDefaultValueForType<T>() {
|
||||||
|
if (T == String) return '' as T;
|
||||||
|
if (T == bool) return false as T;
|
||||||
|
if (T == int) return 0 as T;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
bool _isNullable<T>() => null is T;
|
bool _isNullable<T>() => null is T;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user