267 lines
8.3 KiB
Markdown
267 lines
8.3 KiB
Markdown
# ApexCharts t.put Error Fix - Complete
|
|
|
|
## Issue Description
|
|
The admin evaluation dashboard was experiencing `t.put is not a function` errors when rendering ApexCharts. The error occurred when charts attempted to render on hidden elements or when tab switching caused timing issues with DOM updates.
|
|
|
|
## Root Cause Analysis
|
|
|
|
### Primary Issues Identified:
|
|
1. **Insufficient Visibility Detection**: The `offsetParent` check alone was not comprehensive enough to detect all cases of hidden elements
|
|
2. **Race Conditions**: Charts were attempting to render before the DOM was fully updated after tab switching
|
|
3. **Container Interference**: Clearing `innerHTML` before ApexCharts could initialize was causing conflicts
|
|
4. **Concurrent Renders**: Multiple attempts to render the same chart simultaneously
|
|
|
|
### Error Pattern:
|
|
```
|
|
Uncaught (in promise) TypeError: t.put is not a function
|
|
at addTo @ apexcharts.min.js:6
|
|
at value @ apexcharts:5
|
|
...
|
|
```
|
|
|
|
This error occurred when ApexCharts tried to manipulate a DOM element that wasn't ready or visible.
|
|
|
|
## Solution Implemented
|
|
|
|
### 1. Enhanced Visibility Detection
|
|
**Before:**
|
|
```javascript
|
|
const isVisible = el.offsetParent !== null;
|
|
```
|
|
|
|
**After:**
|
|
```javascript
|
|
const style = window.getComputedStyle(el);
|
|
const isVisible = el.offsetParent !== null &&
|
|
style.display !== 'none' &&
|
|
style.visibility !== 'hidden' &&
|
|
style.opacity !== '0';
|
|
```
|
|
|
|
**Benefits:**
|
|
- Checks multiple CSS properties for comprehensive visibility detection
|
|
- Detects elements hidden via `display: none`, `visibility: hidden`, or `opacity: 0`
|
|
- Prevents rendering on elements that appear to have offsetParent but are still visually hidden
|
|
|
|
### 2. Concurrent Render Prevention
|
|
**Added:**
|
|
```javascript
|
|
const renderingFlags = {};
|
|
|
|
function renderChart(elementId, options) {
|
|
// Prevent concurrent renders
|
|
if (renderingFlags[elementId]) {
|
|
console.log('Chart already rendering, skipping:', elementId);
|
|
return;
|
|
}
|
|
|
|
renderingFlags[elementId] = true;
|
|
|
|
try {
|
|
// Chart rendering logic
|
|
} finally {
|
|
delete renderingFlags[elementId];
|
|
}
|
|
}
|
|
```
|
|
|
|
**Benefits:**
|
|
- Prevents multiple simultaneous render attempts on the same chart
|
|
- Uses a flag system to track rendering state
|
|
- Always clears flag in `finally` block to prevent deadlocks
|
|
|
|
### 3. Improved Chart Instance Cleanup
|
|
**Before:**
|
|
```javascript
|
|
if (chartInstances[elementId]) {
|
|
chartInstances[elementId].destroy();
|
|
}
|
|
|
|
el.innerHTML = '';
|
|
```
|
|
|
|
**After:**
|
|
```javascript
|
|
if (chartInstances[elementId]) {
|
|
try {
|
|
chartInstances[elementId].destroy();
|
|
console.log('Destroyed existing chart instance:', elementId);
|
|
} catch (error) {
|
|
console.warn('Error destroying chart instance:', elementId, error);
|
|
}
|
|
delete chartInstances[elementId];
|
|
}
|
|
|
|
// Removed: el.innerHTML = '';
|
|
// Let ApexCharts handle container cleanup
|
|
```
|
|
|
|
**Benefits:**
|
|
- Proper error handling for destroy operations
|
|
- Explicitly removes from instances dictionary
|
|
- Lets ApexCharts manage its own container (removes manual innerHTML clearing that caused conflicts)
|
|
|
|
### 4. Increased Tab Switching Delay
|
|
**Before:**
|
|
```javascript
|
|
setTimeout(renderInquiryCharts, 50);
|
|
```
|
|
|
|
**After:**
|
|
```javascript
|
|
setTimeout(renderInquiryCharts, 150);
|
|
```
|
|
|
|
**Benefits:**
|
|
- Gives Bootstrap more time to complete tab transitions
|
|
- Ensures DOM is fully updated before attempting chart render
|
|
- Reduces race condition probability
|
|
|
|
### 5. Enhanced Tab Visibility Check
|
|
**Added:**
|
|
```javascript
|
|
function renderInquiryCharts() {
|
|
const inquiriesTabContent = document.getElementById('inquiries');
|
|
if (!inquiriesTabContent) {
|
|
console.warn('Inquiries tab content not found');
|
|
return;
|
|
}
|
|
|
|
const style = window.getComputedStyle(inquiriesTabContent);
|
|
const isTabVisible = inquiriesTabContent.offsetParent !== null &&
|
|
style.display !== 'none' &&
|
|
style.visibility !== 'hidden';
|
|
|
|
if (!isTabVisible) {
|
|
console.log('Inquiries tab not yet visible, delaying render...');
|
|
return;
|
|
}
|
|
|
|
// Proceed with chart rendering
|
|
}
|
|
```
|
|
|
|
**Benefits:**
|
|
- Double-checks tab visibility before rendering
|
|
- Prevents rendering if tab transition is still in progress
|
|
- Provides clear logging for debugging
|
|
|
|
### 6. Improved Error Handling
|
|
**Added:**
|
|
```javascript
|
|
try {
|
|
const chart = new ApexCharts(el, options);
|
|
chart.render();
|
|
chartInstances[elementId] = chart;
|
|
console.log('Chart rendered successfully:', elementId);
|
|
} catch (error) {
|
|
console.error('Error rendering chart:', elementId, error);
|
|
if (chartInstances[elementId]) {
|
|
delete chartInstances[elementId];
|
|
}
|
|
} finally {
|
|
delete renderingFlags[elementId];
|
|
}
|
|
```
|
|
|
|
**Benefits:**
|
|
- Catches and logs all chart rendering errors
|
|
- Cleans up instances on error
|
|
- Always clears rendering flag
|
|
- Provides detailed error context
|
|
|
|
## Testing Performed
|
|
|
|
### 1. Initial Page Load
|
|
- ✅ Complaint charts render successfully on page load
|
|
- ✅ No console errors on initial load
|
|
- ✅ Charts display correctly with data
|
|
|
|
### 2. Tab Switching
|
|
- ✅ Switching from Complaints to Inquiries tab works smoothly
|
|
- ✅ Inquiry charts render after tab is fully visible
|
|
- ✅ No `t.put` errors during tab switching
|
|
- ✅ Charts render with correct data
|
|
|
|
### 3. Chart Interaction
|
|
- ✅ Charts respond to user interactions
|
|
- ✅ Tooltips work correctly
|
|
- ✅ Chart legends function properly
|
|
|
|
### 4. Edge Cases
|
|
- ✅ Handles missing chart elements gracefully
|
|
- ✅ Skips rendering when no data available
|
|
- ✅ Prevents duplicate chart instances
|
|
- ✅ Manages concurrent render attempts
|
|
|
|
## Files Modified
|
|
|
|
### templates/dashboard/admin_evaluation.html
|
|
**Changes:**
|
|
- Enhanced `renderChart()` function with:
|
|
- Multi-property visibility check
|
|
- Concurrent render prevention
|
|
- Improved instance cleanup
|
|
- Better error handling
|
|
|
|
- Updated `renderInquiryCharts()` function with:
|
|
- Tab visibility verification
|
|
- Increased delay (150ms)
|
|
- Detailed logging
|
|
|
|
- Removed manual `innerHTML = ''` clearing
|
|
- Added `renderingFlags` tracking
|
|
|
|
## Performance Impact
|
|
|
|
### Improvements:
|
|
- **Reduced Error Rate**: Eliminated `t.put` errors
|
|
- **Smoother Tab Transitions**: Charts render only when ready
|
|
- **Better Resource Management**: Proper cleanup of chart instances
|
|
|
|
### Minimal Overhead:
|
|
- Visibility checks are fast (CSS property lookups)
|
|
- Rendering flags use minimal memory
|
|
- Increased delay (150ms vs 50ms) is negligible for UX
|
|
|
|
## Browser Compatibility
|
|
|
|
The solution uses standard JavaScript APIs that are widely supported:
|
|
- `window.getComputedStyle()` - IE9+
|
|
- `offsetParent` - All browsers
|
|
- Modern error handling - All browsers
|
|
|
|
## Future Enhancements (Optional)
|
|
|
|
1. **Lazy Loading**: Only load chart library when needed
|
|
2. **Chart Preloading**: Pre-render charts in background for faster tab switching
|
|
3. **Responsive Debouncing**: Adjust delay based on device performance
|
|
4. **Chart Pooling**: Reuse chart instances instead of destroying/recreating
|
|
5. **Progressive Loading**: Render charts in priority order
|
|
|
|
## Monitoring Recommendations
|
|
|
|
1. **Console Logging**: Monitor for chart rendering errors
|
|
2. **Performance Metrics**: Track chart render times
|
|
3. **User Feedback**: Collect reports of any remaining issues
|
|
4. **Browser Testing**: Test across different browsers and devices
|
|
|
|
## Conclusion
|
|
|
|
The ApexCharts `t.put` error has been successfully resolved through a comprehensive multi-layered approach:
|
|
|
|
1. **Better Visibility Detection** - Prevents rendering on hidden elements
|
|
2. **Concurrent Render Prevention** - Stops duplicate render attempts
|
|
3. **Proper Cleanup** - Manages chart instances correctly
|
|
4. **Timing Adjustments** - Allows DOM to fully update before rendering
|
|
5. **Error Handling** - Gracefully handles edge cases
|
|
|
|
The solution maintains performance while significantly improving reliability. All charts now render correctly without errors, providing a smooth user experience on the admin evaluation dashboard.
|
|
|
|
## Implementation Date
|
|
February 6, 2026
|
|
|
|
## Related Documentation
|
|
- [MANUAL_SURVEY_SENDING_IMPLEMENTATION_COMPLETE.md](MANUAL_SURVEY_SENDING_IMPLEMENTATION_COMPLETE.md) - Manual survey sending feature
|
|
- [APEXCHARTS_FIX_COMPLETE.md](APEXCHARTS_FIX_COMPLETE.md) - Previous ApexCharts fixes
|
|
- [ADMIN_EVALUATION_IMPLEMENTATION_COMPLETE.md](ADMIN_EVALUATION_IMPLEMENTATION_COMPLETE.md) - Admin evaluation dashboard implementation |