Skip to content

Search suggestion list

Web / frontend · Difficulty 3/5 · TypeScript · 45 linesOrigin: Real project (anonymized)

Task

What the AI was asked to do

Write createAutocomplete(options), which manages the state of the suggestion list under a search input. As the user types, show the options that start with the typed text (case-insensitive, ignoring leading and trailing spaces, at most 5). Clicking a suggestion with the mouse puts it into the input and closes the list. Leaving the input (blur) closes the list. The page forwards the input's input and blur events and each suggestion's pointerdown and click events to these functions. The list is drawn only while suggestions() is not empty. Keyboard navigation is a separate task.

Handoff note

What the AI wrote when it handed over the code:

“Suggestions are filtered as the user types, a clicked suggestion goes into the input and closes the list, and leaving the input closes it too.”

The code the AI wrote

TypeScript45 lines

Mark the lines you think are wrong; give each mark a severity and a one-sentence reason.

Click or tap a line. With a keyboard, move to the line and press Enter.

0 of 5 marks
How to pick a severity
  • CriticalData loss, a security hole or lost money
  • MajorThe user gets a wrong result in a case the task asks for
  • MinorA rare edge case outside the task, or readability

In the Testing topic, severity is set by the effect of the broken implementation the test doesn't catch.

Your reason isn't graded; you'll compare it with a sample answer.

export function createAutocomplete(options: string[]) {
  let value = "";
  let open = false;
  let pressed = -1;
5
  function matches(): string[] {
    const typed = value.trim().toLowerCase();
    if (typed === "") {
      return [];
    }
    return options
      .filter((option) => option.toLowerCase().startsWith(typed))
      .slice(0, 5);
  }
15
  function choose(index: number): void {
    const option = matches()[index];
    if (option !== undefined) {
      value = option;
      open = false;
      pressed = -1;
    }
  }
24
  return {
    value: () => value,
    suggestions: () => (open ? matches() : []),
    pressedIndex: () => pressed,
    input(text: string): void {
      value = text;
      pressed = -1;
      open = matches().length > 0;
    },
    blur(): void {
      open = false;
      pressed = -1;
    },
    optionPointerDown(index: number): void {
      pressed = index;
    },
    optionClick(index: number): void {
      choose(index);
    },
  };
}

The test that proves it

The right option is the test that fails on this code, which means it exposes the bug.

Test options
Mark at least one line to submit.

Submitting sends seven pieces of information to a counter; your reason text stays on your device. Data