The documentation has been corrected to show the proper NormalJS pattern: direct property modification.
❌ Incorrect (shown before):
const user = await Users.findById(1);
await user.update({ email: 'new@example.com' }); // update() doesn't exist!✅ Correct (optimal NormalJS way):
const user = await Users.findById(1);
user.email = 'new@example.com'; // Direct modification
// Changes persist automatically on next query or transaction flush
// Or force immediate write:
await user.write();-
Direct Property Modification (Optimal)
- Modify properties directly:
record.field = newValue - Changes are tracked automatically
- Persist on next query or when transaction flushes
- This is the most efficient way
- Modify properties directly:
-
Manual Persistence (When Needed)
- Use
await record.write()to force immediate persistence - No
update()method exists - No
save()method exists
- Use
-
Deletion
- Use
await record.unlink()to delete - No
delete()method exists
- Use
- ✅ Fixed "When handling records" section
- ✅ Fixed "Query Patterns" section
- ✅ Removed all incorrect
update()examples - ✅ Added correct direct modification patterns
- ✅ Documented
write()method for manual persistence
- ✅ Fixed "Complete Working Example" (step 9)
- ✅ Fixed "How to: Update and Delete" section
- ✅ Fixed "How to: Use Transactions" section
- ✅ Removed all
update()calls - ✅ Shows direct property modification throughout
- ✅ Fixed "Update Records" section in CRUD Operations
- ✅ Fixed transaction examples (inventory deduction, order totals)
- ✅ Fixed authentication
setPassword()method - ✅ Fixed timestamps example
- ✅ Fixed soft delete methods (
softDelete()andrestore()) - ✅ Fixed slug generation
post_create()hook - ✅ Fixed search
post_update()hook - ✅ All examples now use direct modification
- ✅ Fixed "Update Records" section
- ✅ Fixed many-to-one relation usage
- ✅ Shows ❌ DON'T use
update()explicitly - ✅ Shows ✅ DO use direct modification
const user = await Users.findById(1);
user.email = 'new@example.com';
user.name = 'New Name';
// Persists automaticallyconst user = await Users.findById(1);
user.email = 'new@example.com';
await user.write(); // Force immediate persistenceawait repo.transaction(async tx => {
const Users = tx.get('Users');
const user = await Users.findById(1);
user.email = 'new@example.com';
user.updated_at = new Date();
// Persists on transaction commit
});const user = await Users.findById(1);
if (user.role !== 'admin') {
user.email = newEmail;
await user.write();
}The documentation now explicitly shows what NOT to do:
❌ await user.update({ ... }) - Method doesn't exist
❌ await user.save() - Method doesn't exist
❌ await user.delete() - Use unlink() instead
❌ Thinking changes won't persist - They do!
✅ Documentation builds successfully ✅ All examples corrected ✅ Consistent patterns throughout ✅ AI agents will now learn the correct NormalJS way
When working with NormalJS records:
- Always modify properties directly - This is the optimal pattern
- Changes persist automatically - On next query or transaction flush
- Use
write()for immediate persistence - Only when you need it right away - No
update()method exists - Don't look for it - No
save()method exists - Direct modification handles it