[FIX] Node initialization logic for non-dynamic values.

This commit is contained in:
2026-01-27 14:28:39 +02:00
parent 229ab02f6d
commit 53cd7da463

View File

@@ -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;