Add Additional Logic to Existing Methods
Overview
Sometimes you need to add extra logic to an existing controller method without completely replacing it. This approach allows you to extend the out-of-the-box functionality by subscribing to the same event and adding your custom processing alongside the original method.
Use Cases:
- Adding logging to track method execution
- Performing additional validation before/after an action
- Triggering side effects when certain events occur
- Extending functionality without modifying core controllers
Prerequisites:
- Understanding of MAF lifecycle events
- Familiarity with AppCustomizations.js
- Knowledge of JavaScript event handling
Important Note:
⚠️ The execution order of methods with the same name cannot be guaranteed. All methods subscribed to an event are called, but the sequence is not enforced by the platform. If order matters, use Replace Existing Method instead.
Implementation
Step 1: Identify the method to extend
Find the event or method you want to add logic to. This can be done by:
- Inspecting the XML - Look for event handlers in your app.xml:
<!-- Example: Dialog with secondary action --><dialog id="saveDiscardWorkLog"on-secondary-action="closeWorkLogSaveDiscard"secondary-action-text="Discard"><!-- Dialog content --></dialog>
Checking the controller - Review the out-of-the-box controller to understand what the original method does
Using browser DevTools - Set breakpoints to see when methods are called
Step 2: Create the method in AppCustomizations.js
Add a method with the exact same name and signature as the original method:
AppCustomizations.js:
/*** Custom Application Logic*/const TAG = 'CustomWorkLog';class AppCustomizations {/*** Initialize application* @param {Application} app - The application instance
Step 3: Test the implementation
- Trigger the event - Perform the action that calls the method
- Check logs - Verify your custom logic executes
- Verify original behavior - Ensure the out-of-the-box functionality still works
- Test edge cases - Try different scenarios to ensure stability
Complete Examples
Example 1: Adding Validation to Save Action
const TAG = 'CustomValidation';class AppCustomizations {applicationInitialized(app) {this.app = app;}/*** Add custom validation when saving work order
Example 2: Tracking Page Navigation
const TAG = 'NavigationTracker';class AppCustomizations {applicationInitialized(app) {this.app = app;this.navigationHistory = [];}/**
Example 3: Adding Logging to Multiple Events
const TAG = 'EventLogger';class AppCustomizations {applicationInitialized(app) {this.app = app;}/*** Log when datasource loads data
Validation & Testing
How to verify:
Enable debug logging:
?_graphite_logLevel=debugTrigger the event:
- Perform the action that calls the method
- Check browser console for your log messages
Verify both methods run:
- Confirm out-of-the-box behavior works
- Confirm your custom logic executes
Test error scenarios:
- What happens if your code throws an error?
- Does the original method still execute?
Common Issues:
Issue: Custom logic doesn’t execute
- Cause: Method name or signature doesn’t match exactly
- Solution: Verify method name spelling and parameters
Issue: Original functionality breaks
- Cause: Error in custom code prevents execution
- Solution: Add try-catch blocks and proper error handling
Issue: Execution order matters but isn’t guaranteed
- Cause: Platform doesn’t enforce order for parallel methods
- Solution: Use Replace Existing Method instead
Best Practices
✅ Do:
- Add comprehensive logging to track execution
- Use try-catch blocks to prevent breaking original functionality
- Document why you’re adding the logic
- Test thoroughly in all scenarios
- Keep custom logic focused and minimal
- Use descriptive method names in logs
❌ Don’t:
- Rely on execution order (it’s not guaranteed)
- Modify parameters that affect the original method
- Add heavy processing that impacts performance
- Forget error handling
- Assume your method runs before or after the original
Performance Considerations:
- Keep additional logic lightweight
- Avoid synchronous operations that block
- Use async/await for I/O operations
- Consider impact on mobile devices
Error Handling:
closeWorkLogSaveDiscard() {try {// Your custom logicthis.app.log.d(TAG, 'Custom logic executing');this.performCustomAction();} catch (error) {// Don't let errors break the original functionalitythis.app.log.e(TAG, 'Error in custom logic', error);}
Comparison: Additional Logic vs Replace Method
| Aspect | Additional Logic | Replace Method |
|---|---|---|
| Complexity | Simple | More complex |
| Execution Order | Not guaranteed | Fully controlled |
| Original Method | Runs unchanged | You control if/when it runs |
| Use Case | Side effects, logging | Modify core behavior |
| Risk | Low | Higher |
| Maintenance | Easier | Requires updates on upgrades |
When to use Additional Logic:
- Adding logging or analytics
- Triggering side effects
- Validation that doesn’t block
- Tracking user actions
When to use Replace Method:
- Need to control execution order
- Must modify original behavior
- Need to prevent original execution
- Complex conditional logic
Related Resources
Prerequisites:
Related Practices:
- Replace Existing Method - For controlled execution
- Datasources Guide - Lifecycle Events
Next Steps:
- Restrict Complete Status - Complex validation example
- Set Default Values - Using lifecycle events
External Documentation:
Additional Notes
Debugging Tips:
Use unique log tags:
const TAG = 'CustomFeature_MethodName';Log entry and exit:
methodName() {this.app.log.d(TAG, 'Method started');// Your logicthis.app.log.d(TAG, 'Method completed');}Log important values:
this.app.log.d(TAG, `Processing item: ${JSON.stringify(item)}`);
Event Naming Conventions:
Some events don’t have aliases and must be quoted:
// Events with dashes need quotes'field-warning'(event) {// Handle field warning}'before-invoke-action'(event) {// Handle before action}
See FAQ - How to handle events with no alias for more details.