Skip to content

Commit 62fcafc

Browse files
authored
Forms 1.0.15: Fix null value handling and form submission error detection (#725)
* Fix null value handling and form submission error detection - Fixed critical null value handling in JSP/getFilteredProps/getAllPropertyNames functions to prevent 'TypeError: null is not an object' errors - Fixed form submission success detection - undefined is now treated as success when templateRunner creates a note (was incorrectly flagged as error) - Added deep null sanitization throughout form data processing - Made templateNew return filename for API consistency - Updated templateRunner to return filename on successful note creation - Removed setTimeout usage (not available in NotePlan JSContext) - Improved error messages for better debugging Version bump to 1.0.15 * Refactor: Move data fetching functions to dataHandlers.js and improve error handling - Moved getFolders, getNotes, getEvents, getHashtags, getMentions, getTeamspaces from requestHandlers.js to new dataHandlers.js to break circular dependencies - Moved RequestResponse type to shared/types.js for better type sharing - Improved error handling in FormBrowserView for form submission responses - Updated imports across affected files
1 parent 81589ec commit 62fcafc

14 files changed

Lines changed: 1185 additions & 663 deletions

File tree

dwertheimer.Forms/CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,26 @@
44

55
See Plugin [README](https://github.com/NotePlan/plugins/blob/main/dwertheimer.Forms/README.md) for details on available commands and use case.
66

7+
## [1.0.15] 2026-01-18 @dwertheimer
8+
9+
### Fixed
10+
- **CRITICAL: Null Value Handling**: Fixed `TypeError: null is not an object (evaluating 'Object.getOwnPropertyNames')` error that occurred when templating plugin tried to process form data containing null values. Added explicit null checks in `JSP`, `getFilteredProps`, and `getAllPropertyNames` helper functions to handle null values correctly (since `typeof null === 'object'` in JavaScript).
11+
- **Form Submission Success Detection**: Fixed issue where successful form submissions were incorrectly flagged as errors. When `templateRunner` successfully creates a note via `templateNew`, it returns `undefined` (which is valid), but the code was treating this as an error. Now only `null` or empty strings are treated as errors.
12+
- **Deep Null Sanitization**: Added comprehensive deep sanitization of null/undefined values throughout form data processing. All null/undefined values are now converted to empty strings recursively before being passed to the templating engine, preventing errors in nested data structures.
13+
- **setTimeout Removal**: Removed `setTimeout` usage in form submission handlers (not available in NotePlan's JSContext). Replaced with proactive cleanup mechanism using a Map to manage debouncing without timeouts.
14+
15+
### Changed
16+
- **templateNew Return Value**: Updated `templateNew` to return the filename (string) on success or `null` on failure, making the API more consistent and explicit. Previously returned `undefined`, which made it difficult to distinguish success from failure.
17+
- **templateRunner Return Value**: Updated `templateRunner` to return the filename when a note is successfully created, instead of returning `undefined`. This provides explicit feedback about successful operations.
18+
- **Error Messages**: Improved error messages to be more specific about null value issues and provide better guidance for debugging template execution problems.
19+
20+
## [1.0.14] 2026-01-18 @dwertheimer
21+
22+
### Fixed
23+
- **Form Submission Error Detection**: Fixed issue where FormBrowserView showed success message even when template execution failed. Now properly detects and displays errors from template processing, including AI analysis results and form submission errors.
24+
- **Form Field Validation**: Added validation to ensure all form fields are included in submission, even if left blank. This prevents template errors from missing variables. Validation now occurs both in FormBrowserView handler and in handleSubmitButtonClick.
25+
- **Error Message Display**: Improved error messages to be more specific. FormBrowserView now shows detailed error messages instead of generic "success" when template execution fails. Error messages include information about missing variables and template rendering issues.
26+
727
## [1.0.13] 2026-01-18 @dwertheimer
828

929
### Changed

dwertheimer.Forms/plugin.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"noteplan.minAppVersion": "3.4.0",
55
"plugin.id": "dwertheimer.Forms",
66
"plugin.name": "📝 Template Forms",
7-
"plugin.version": "1.0.13",
7+
"plugin.version": "1.0.15",
88
"plugin.releaseStatus": "beta",
9-
"plugin.lastUpdateInfo": "Dark Mode CSS theme color fixes, FormPreview scaled warning improvements, text color styling updates, Form Browser @Templates support, Toast notifications, fixed form submission to include all fields, and fixed Target Note field to use template values for special options",
9+
"plugin.lastUpdateInfo": "Fixed critical null value handling in templating plugin, fixed form submission success detection, added deep null sanitization, and improved API consistency",
1010
"plugin.description": "Dynamic Forms for NotePlan using Templating -- fill out a multi-field form and have the data sent to a template for processing",
1111
"plugin.author": "dwertheimer",
1212
"plugin.requiredFiles": ["react.c.FormView.bundle.dev.js", "react.c.FormBuilderView.bundle.dev.js", "react.c.FormBrowserView.bundle.dev.js"],

dwertheimer.Forms/src/components/FormBrowserView.jsx

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,17 @@ export function FormBrowserView({
526526
const handleSave = useCallback(
527527
(formValues: Object, windowId?: string) => {
528528
logDebug('FormBrowserView', 'Form submitted:', formValues)
529+
530+
// Clear any previous errors before submitting
531+
dispatch('UPDATE_DATA', {
532+
...data,
533+
pluginData: {
534+
...pluginData,
535+
formSubmissionError: '',
536+
aiAnalysisResult: '',
537+
},
538+
})
539+
529540
// Send to plugin for processing
530541
// Include keepOpenOnSubmit flag so the plugin knows not to close the window
531542
if (requestFromPlugin) {
@@ -537,6 +548,60 @@ export function FormBrowserView({
537548
})
538549
.then((responseData) => {
539550
logDebug('FormBrowserView', 'Form submission response:', responseData)
551+
552+
// Check if the response indicates success or failure
553+
// The responseData may be the data object from a successful response, or it may contain error info
554+
if (responseData && typeof responseData === 'object') {
555+
// Check for error indicators in the response (from pluginData)
556+
const pluginDataFromResponse = responseData.pluginData || {}
557+
const hasError = pluginDataFromResponse.formSubmissionError || pluginDataFromResponse.aiAnalysisResult || responseData.formSubmissionError || responseData.aiAnalysisResult
558+
if (hasError) {
559+
// Extract error message
560+
let errorMessage = 'Form submission failed.'
561+
const formError = pluginDataFromResponse.formSubmissionError || responseData.formSubmissionError
562+
const aiError = pluginDataFromResponse.aiAnalysisResult || responseData.aiAnalysisResult
563+
564+
if (formError) {
565+
errorMessage = formError
566+
} else if (aiError) {
567+
// Extract a brief summary from AI analysis
568+
const aiMsg = aiError
569+
const firstLine = aiMsg.split('\n')[0] || aiMsg.substring(0, 200)
570+
errorMessage = `Template error: ${firstLine}`
571+
}
572+
573+
logError('FormBrowserView', `Form submission failed: ${errorMessage}`)
574+
575+
// Update pluginData with error so FormErrorBanner can display it
576+
dispatch('UPDATE_DATA', {
577+
...data,
578+
pluginData: {
579+
...pluginData,
580+
formSubmissionError: formError || errorMessage,
581+
aiAnalysisResult: aiError || '',
582+
},
583+
})
584+
585+
dispatch('SHOW_TOAST', {
586+
type: 'ERROR',
587+
msg: errorMessage,
588+
timeout: 10000, // Longer timeout for error messages
589+
})
590+
// Don't reset form on error - keep it open so user can fix and retry
591+
return
592+
}
593+
}
594+
595+
// Clear any errors on successful submission
596+
dispatch('UPDATE_DATA', {
597+
...data,
598+
pluginData: {
599+
...pluginData,
600+
formSubmissionError: '',
601+
aiAnalysisResult: '',
602+
},
603+
})
604+
540605
// Show success toast with note information
541606
let successMessage = 'Your form has been submitted successfully.'
542607
if (responseData?.noteTitle) {
@@ -568,16 +633,27 @@ export function FormBrowserView({
568633
logError('FormBrowserView', `Error submitting form: ${error.message}`)
569634
// On error, show Toast notification but don't close the window
570635
// The window should stay open so user can fix and retry
636+
const errorMessage = error.message || 'An error occurred while submitting the form'
637+
638+
// Update pluginData with error so FormErrorBanner can display it
639+
dispatch('UPDATE_DATA', {
640+
...data,
641+
pluginData: {
642+
...pluginData,
643+
formSubmissionError: errorMessage,
644+
},
645+
})
646+
571647
dispatch('SHOW_TOAST', {
572648
type: 'ERROR',
573-
msg: error.message || 'An error occurred while submitting the form',
574-
timeout: 5000,
649+
msg: errorMessage,
650+
timeout: 10000, // Longer timeout for error messages
575651
})
576652
// Don't reset form on error - let user see what they entered
577653
})
578654
}
579655
},
580-
[selectedTemplate, requestFromPlugin, handleCancel, dispatch],
656+
[selectedTemplate, requestFromPlugin, handleCancel, dispatch, data, pluginData],
581657
)
582658

583659

0 commit comments

Comments
 (0)