---
title: "Show the answer to the latest request only · Agent Wranglers"
url: https://agentwranglers.se/playbook/app-ui/client-and-server-state/latest-request-wins
updated: 2026-10-20
licence: "All rights reserved"
---

# Show the answer to the latest request only

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Client and server state](https://agentwranglers.se/playbook/app-ui/client-and-server-state)
- Rule: When a new request replaces an older one, such as a new search term, abort the older request and never render its answer.
- How: Answers can arrive out of order, so a slow answer for "ab" can overwrite the results for "abc". Abort the previous request with an `AbortController` when a new one starts. Also check that the answer belongs to the current input before rendering it. Cache libraries that key by input, such as TanStack Query, do both. Wait for a pause of about 300 ms in typing before searching. In htmx, `hx-sync="this:replace"` aborts the older request.
- Check: A browser test types "ab" and then "abc", and holds back the answer for "ab" until the results for "abc" show. The results for "abc" still show after the held answer is released.

Example:

```ts
let current: AbortController | undefined;

export async function search(term: string, render: (results: Result[]) => void) {
  current?.abort();
  const controller = new AbortController();
  current = controller;
  try {
    const response = await fetch(`/api/search?q=${encodeURIComponent(term)}`, { signal: controller.signal });
    const results = await response.json();
    if (controller === current) render(results);
  } catch (error) {
    if (!(error instanceof DOMException && error.name === 'AbortError')) throw error;
  }
}
```

```python
import re
from playwright.sync_api import Error, expect

def test_old_answer_never_replaces_new_one(page):
    held_back = []
    answer_for_ab = re.compile(r"/api/search\?q=ab$")
    page.route(answer_for_ab, held_back.append)
    page.goto("https://staging.example.com/customers")
    search = page.get_by_role("searchbox", name="Search customers")
    with page.expect_request(answer_for_ab):
        search.fill("ab")
    search.fill("abc")
    expect(page.get_by_role("status")).to_have_text("Results for abc")
    for route in held_back:
        try:
            route.continue_()
        except Error:
            pass
    page.wait_for_timeout(1000)
    expect(page.get_by_role("status")).to_have_text("Results for abc")
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers app interface playbook: https://agentwranglers.se/playbook/app-ui/client-and-server-state/latest-request-wins`.

- Previous: [Key cached data by every input](https://agentwranglers.se/playbook/app-ui/client-and-server-state/complete-cache-keys)
- Next: [Refresh every view a change touches](https://agentwranglers.se/playbook/app-ui/client-and-server-state/refresh-after-change)
- [Client and server state](https://agentwranglers.se/playbook/app-ui/client-and-server-state)
