Interview question
Fix stale OnPush UI updated by a third-party callback
Repairs a stale view by bringing an external callback into explicit Angular state ownership without adding polling or global change detection.
TL;DR
Repairs a stale view by bringing an external callback into explicit Angular state ownership without adding polling or global change detection.
Angular OnPush, zoneless change detection, third-party callbacks, signals, DestroyRef, cleanup, and integration boundaries.
Practice the problem like a real interview: restate, reason, implement, and test.
A map SDK calls onSelectionChanged outside Angular, assigns a plain selectedPlace field, and the OnPush view stays stale until another click. Refactor the wrapper so the callback updates a signal, the view renders immediately in zoneless mode, and the SDK listener is removed when the component is destroyed. Do not add polling, ApplicationRef.tick, or a global Zone workaround.
SDK emits Place A -> heading immediately shows Place A
SDK emits Place B -> heading shows Place B
component destroyed -> listener removed; later SDK events do nothing
import {ChangeDetectionStrategy, Component, DestroyRef, inject, signal} from '@angular/core';
@Component({
selector: 'app-map-selection',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@if (selectedPlace(); as place) {
<h2>{{ place.name }}</h2>
} @else {
<p>Select a place on the map.</p>
}
`,
})
export class MapSelection {
private readonly sdk = inject(MapSdk);
private readonly destroyRef = inject(DestroyRef);
readonly selectedPlace = signal<Place | null>(null);
constructor() {
const removeListener = this.sdk.onSelectionChanged(place => {
this.selectedPlace.set({id: place.id, name: place.name});
});
this.destroyRef.onDestroy(removeListener);
}
}
Each SDK event performs O(1) state replacement and schedules only the views that consume the signal.
Next in Angular Practical Labs: Third-party widget teardown