From 53cd7da463b47d555b66fc65dbe734b3c5449f5c Mon Sep 17 00:00:00 2001 From: Michael Aziz Date: Tue, 27 Jan 2026 14:28:39 +0200 Subject: [PATCH] [FIX] Node initialization logic for non-dynamic values. --- lib/src/form/src/controller.dart | 39 ++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/lib/src/form/src/controller.dart b/lib/src/form/src/controller.dart index 2bbe9e8..0efef6e 100644 --- a/lib/src/form/src/controller.dart +++ b/lib/src/form/src/controller.dart @@ -74,38 +74,37 @@ class AstromicFormController { if (_nodes.containsKey(id)) { final existingNode = _nodes[id]!; - // Check if the existing node is already the correct type if (existingNode is AstromicFieldNode) { return existingNode; } - // If it's a type mismatch (likely ), we must migrate it. - // We create a new node of the correct type using the existing value. + // Determine a safe value for the replacement node + 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(); + } + final replacementNode = AstromicFieldNode( - existingNode.value as T, + migratedValue as T, // Should be safe now formatter: (v) => v?.toString() ?? '', parser: (v) => (T == String ? v : null) as T?, ); - // Transfer validators if they exist replacementNode.validators = existingNode.validators; - _nodes[id] = replacementNode; return replacementNode; } - // Fallback for new nodes (keep your existing lazy-init logic here) - T? defaultValue = initialValue; - 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; - } + // Fallback for brand-new nodes + final T startValue = initialValue ?? _getDefaultValueForType() as T; final newNode = AstromicFieldNode( - defaultValue as T, + startValue, formatter: (v) => v?.toString() ?? '', parser: (v) => (T == String ? v : null) as T?, ); @@ -114,7 +113,13 @@ class AstromicFormController { return newNode; } - Type _typeOf() => T; + /// Helper to ensure we never pass a null to a non-nullable Node constructor + T? _getDefaultValueForType() { + if (T == String) return '' as T; + if (T == bool) return false as T; + if (T == int) return 0 as T; + return null; + } bool _isNullable() => null is T;