Troubleshooting
Common issues and their solutions when using Form Guardian.
🔍 Common Issues
Draft Not Saving
Symptoms: Form changes are not being saved automatically.
Possible Causes & Solutions:
-
IndexedDB not available
// Check if IndexedDB is available
if (!window.indexedDB) {
console.error('IndexedDB is not supported in this browser');
} -
Form not properly attached
// Make sure formRef is attached AFTER component mount
useEffect(() => {
// ✅ Correct
if (formRef.current) {
attachFormAutosave({ ... });
}
}, []); -
Debounce delay too high
// Reduce debounce for testing
useFormAutosave('my-form', {
debounceMs: 100, // Lower value for faster saving
}); -
Fields excluded by blacklist
// Check if fields are being excluded
useFormAutosave('my-form', {
// Password fields are excluded by default
blacklist: [], // Clear blacklist for testing
});
Draft Not Restoring
Symptoms: Saved draft is not being restored on page load.
Solutions:
-
Check
autoRestoreoptionuseFormAutosave('my-form', {
autoRestore: true, // ✅ Must be true
}); -
Form ID mismatch
// Make sure formId is consistent
// ❌ Wrong
useFormAutosave('my-form-' + Date.now(), { ... });
// ✅ Correct
useFormAutosave('my-form', { ... }); -
For controlled forms (React Hook Form, Formik)
// Manual restore required for controlled forms
const { restoreValues, formRef } = useFormAutosave('my-form', {
autoRestore: false, // Important!
});
useEffect(() => {
restoreValues(setValue, getValues); // Manual restore
}, []);
Draft Expired Unexpectedly
Symptoms: Draft disappears after a short time.
Solution:
// Increase TTL
useFormAutosave('my-form', {
ttl: { days: 30 }, // Keep drafts for 30 days
});
Performance Issues
Symptoms: Page becomes slow when typing in form.
Solutions:
-
Increase debounce
useFormAutosave('my-form', {
debounceMs: 1000, // Wait 1 second after typing stops
}); -
Use batch saving
useFormAutosave('my-form', {
batchSaveInterval: 5000, // Save every 5 seconds
debounceMs: 500,
}); -
Use whitelist instead of scanning all fields
useFormAutosave('my-form', {
whitelist: [
'input[name="title"]',
'textarea[name="content"]',
], // Only watch specific fields
});
React: "Cannot read property 'current' of undefined"
Symptom: Error when trying to use formRef.
Solution:
// Make sure formRef is defined and attached
const { formRef } = useFormAutosave('my-form', { ... });
return (
<form ref={formRef}> {/* ✅ Attach ref to form */}
{/* ... */}
</form>
);
Vue: Draft not saving on unmount
Solution:
<script setup>
// Make sure to call destroy()
onBeforeUnmount(() => {
autosave?.destroy(); // ✅ Cleanup
});
</script>
Angular: "formElement is undefined"
Solution:
ngOnInit() {
// Wait for view to initialize
setTimeout(() => {
this.autosave = attachFormAutosave({
root: this.formElement.nativeElement,
// ...
});
}); // ✅ Use setTimeout
}
🐛 Debugging Tips
Enable Console Logging
useFormAutosave('my-form', {
onBeforeSave: (values) => {
console.log('💾 Saving draft:', values);
},
onAfterSave: (values) => {
console.log('✅ Draft saved successfully');
},
onBeforeRestore: (values) => {
console.log('🔄 Restoring draft:', values);
},
onAfterRestore: (values) => {
console.log('✅ Draft restored successfully');
},
onDraftExpired: (draftId) => {
console.log('⏰ Draft expired:', draftId);
},
});
Check IndexedDB Manually
- Open DevTools (F12)
- Go to Application tab
- Expand IndexedDB → form-guardian-db
- Check drafts object store
Verify Form Values
const { getCurrentValues } = useFormAutosave('my-form', { ... });
// Check what values Form Guardian sees
const handleDebug = async () => {
const values = await getCurrentValues();
console.log('Current form values:', values);
};
🔧 Advanced Troubleshooting
Clear All Drafts (Reset)
import { clearAllDrafts } from '@form-guardian/core';
// Clear all drafts from IndexedDB
await clearAllDrafts();
Check Draft Existence
const { hasDraft, getDraftMeta } = useFormAutosave('my-form', { ... });
const checkDraft = async () => {
const exists = await hasDraft();
if (exists) {
const meta = await getDraftMeta();
console.log('Draft exists:', meta);
}
};
Custom Storage Backend
If IndexedDB is not available, use localStorage:
import { saveDraftCore, loadDraftCore } from '@form-guardian/core';
// Implement custom storage
const customSave = async (formId, values) => {
localStorage.setItem(`draft-${formId}`, JSON.stringify(values));
};
const customLoad = async (formId) => {
const data = localStorage.getItem(`draft-${formId}`);
return data ? JSON.parse(data) : null;
};
💬 Still Having Issues?
- Check the FAQ
- Search existing issues
- Open a new issue
Include the following in your issue report:
- Form Guardian version
- Framework and version (React 18, Vue 3, etc.)
- Browser and version
- Code snippet that reproduces the issue
- Console errors (if any)