Interview question
Prove an Angular search cannot be overwritten by an older HTTP response
Uses fake time and HttpTestingController to complete requests out of order and prove latest-query state, recovery, and teardown.
TL;DR
Uses fake time and HttpTestingController to complete requests out of order and prove latest-query state, recovery, and teardown.
HttpTestingController, fake time, request cancellation, switchMap, stale-response races, errors, and outstanding-request verification.
Practice the problem like a real interview: restate, reason, implement, and test.
Write deterministic tests for the cancellable typeahead. Start query A, then query B, and attempt to complete A after B becomes active. Prove only B can own the rendered state. Also prove a failed request does not terminate later searches and no requests remain after the test.
query "ang" -> request A
query "angular" -> request B; A becomes cancelled
flush B -> B results render
attempt A result -> A cannot replace B
HttpTestingController.verify() after every test.import {fakeAsync, TestBed, tick} from '@angular/core/testing';
import {provideHttpClient} from '@angular/common/http';
import {HttpTestingController, provideHttpClientTesting} from '@angular/common/http/testing';
it('keeps only the latest search result', fakeAsync(() => {
TestBed.configureTestingModule({
imports: [Typeahead],
providers: [provideHttpClient(), provideHttpClientTesting()],
});
const http = TestBed.inject(HttpTestingController);
const fixture = TestBed.createComponent(Typeahead);
const component = fixture.componentInstance;
component.updateQuery('ang');
tick(250);
const oldRequest = http.expectOne('/api/search?q=ang');
component.updateQuery('angular');
tick(250);
const latestRequest = http.expectOne('/api/search?q=angular');
expect(oldRequest.cancelled).toBe(true);
latestRequest.flush([{id: '2', label: 'Angular'}]);
tick();
expect(component.state()).toEqual({
kind: 'ready',
results: [{id: '2', label: 'Angular'}],
});
http.verify();
}));
The test is O(1) requests and state transitions and uses no wall-clock waiting, so runtime remains deterministic.
switchMap intentionally and confirm the regression test fails.verify allows accidental background requests.Next in Angular Practical Labs: Zoneless signal component test