Debug an Angular UI from User Reports
WaymoFrontend Engineer · OnsiteLast updated
This problem tests your ability to debug an Angular component, specifically focusing on Change Detection strategies, memory leaks in RxJS subscriptions, and asynchronous state management.
The Problem: The Stale Simulation Monitor
You are working on a Simulation Monitor dashboard in Angular. Users report that the component frequently displays "stale" simulation progress data even when new WebSocket messages are received. Additionally, the browser tab memory usage climbs steadily while the monitor is active.
Current Implementation
@Component({
selector: 'app-sim-monitor',
template: `
Status: {{ status }}
Toggle Updates
`
})
export class SimMonitorComponent implements OnInit {
status = 'Disconnected';
constructor(private simService: SimulationService) {}
ngOnInit() {
this.simService.getUpdates().subscribe(data => {
this.status = data.status;
console.log('Update received:', data);
});
}
togglePolling() {
this.simService.toggle();
}
}
Known Issues
- Memory Leak: The
getUpdates()observable is never unsubscribed, leading to detached subscriptions if the component is destroyed and recreated. - Change Detection: The UI does not always reflect changes immediately, despite the
statusvariable updating correctly in the logic. - Race Conditions: Rapidly toggling polling triggers multiple concurrent subscriptions.
Your Task
- Explain why the UI fails to update and why memory increases.
- Provide a refactored version of the
ngOnInitand cleanup logic. - Write a conceptual unit test (using Jasmine/Karma style) to verify that the subscription is cleaned up when the component is destroyed.
Hints
Hint 1
Consider the lifecycle hooks available in Angular for handling resource cleanup when a component is destroyed.
Hint 2
Think about using the 'async' pipe in the template instead of manual subscription, or implementing the 'takeUntil' pattern.
Hint 3
The OnPush change detection strategy is often used in performance-sensitive dashboards; consider how it interacts with manual data updates.
Follow-up questions
- How would you optimize this component if the SimulationService pushed updates 60 times per second?
- Explain the difference between 'ngOnDestroy' and the 'takeUntil' operator in terms of component robustness.
- If you were to introduce a 'Loading' state, how would you ensure the UI remains responsive during slow WebSocket reconnection attempts?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.