FullStack Course LogoFullStack Course
Module: Machine Coding
Machine Coding·245·11 MIN READ

245: Frontend Machine-Coding Challenge: Data Table / Dashboard

TOPICS COVERED: Frontend Machine-Coding Challenge: Data Table / Dashboard

Learning outcomes

By the end of this lesson, you can:

  • explain and apply table semantics in a realistic implementation;
  • explain and apply sorting in a realistic implementation;
  • explain and apply filtering and search in a realistic implementation;
  • explain and apply pagination in a realistic implementation;
  • explain and apply selection and bulk actions in a realistic implementation.

Prerequisites and retrieval

This lesson assumes that you have completed the earlier 01–06 foundation and the preceding lessons in this module. Before you begin, retrieve one concrete example from an earlier project in which one of these concerns appeared. You are not trying to recite terminology. You are trying to make a defensible decision in a timed machine-coding exercise, while keeping the result readable, accessible, testable, and straightforward to extend when interview time is limited.

Terminology

  • Table semantics: Use semantic table markup for genuinely tabular data. Give sortable columns accessible header and button names so the relationship between a value, its heading, and its sort control remains clear.
  • Sorting: Decide whether sorting is stable, which data-type comparators apply, where null values belong, and whether the client or server owns the operation.
  • Filtering and search: Separate local filtering from server-side filtering. Debounce an expensive remote search, but do not add a debounce merely to disguise cheap local work.
  • Pagination: Use bounded pages or cursors, and preserve the active filters and sort when the user navigates between result sets.
  • Selection and bulk actions: Selection across pages needs an explicit model: current-page IDs, an explicit set of selected IDs, or “all matching except exclusions.” The UI should make that model and its consequences clear.
  • Responsive and accessible UX: Keyboard-accessible controls, visible focus, text alternatives, readable loading states, and mobile overflow or an alternate layout are part of the implementation contract, not polish to add at the end.

Mental model

Treat Frontend Machine-Coding Challenge: Data Table / Dashboard as a bounded design problem with observable inputs, outputs, invariants, and failure modes. A realistic timed frontend challenge brings several concerns together: component architecture, URL or query state, server data, sorting and filtering, accessibility, and tests. A strong solution does not merely render the happy path. It makes assumptions visible, contains uncertainty at boundaries, and leaves evidence—types, tests, constraints, metrics, or diagrams—that explains why the design is safe.

A useful sequence for both an interview and production work is:

text
requirement -> constraints -> model -> implementation -> failure analysis -> verification

Do not move straight from a requirement to a library call. First write down what must remain true. Then choose the mechanism that enforces those invariants. For example, “the user can sort orders” is incomplete until you know which fields are sortable, how nulls behave, whether the server applies the sort, and what happens when the request fails.

Deep dive

1. Table semantics

Start with the relationship the user needs to understand: each cell belongs to a row, and each column has a heading. For tabular data, semantic table markup communicates that relationship to browsers and assistive technology. Sortable headers also need accessible names that describe both the column and the action. Responsive behavior must preserve those relationships rather than turning a table into a collection of unrelated cards without an equivalent structure.

Decision rule: Use table semantics deliberately when they make the contract or invariant easier to prove. If an approach only reduces typing while hiding an assumption, prefer the more explicit design.

2. Sorting

Sorting is more than calling sort. Define whether equal values retain their original order, which comparator belongs to each data type, and where null or missing values appear. Decide whether the result is sorted locally or whether the server owns the ordering. That ownership affects the request contract, pagination, loading states, and what the URL should represent.

There is also a practical data-integrity issue: do not sort a query result in place when the cache treats that result as shared immutable data. Copy the collection or ask the data layer for a transformed result instead. Otherwise, one table can silently change the order observed by another consumer.

Decision rule: Use sorting deliberately when it makes the contract or invariant easier to prove. If it only reduces typing while hiding an assumption, prefer the more explicit design.

The useful distinction is where the filtering happens. A small, already-loaded collection can often be filtered locally. A large or server-backed collection should normally send filter criteria to the server, where the full dataset and its indexing strategy are available. Remote search may need debouncing to avoid sending a request for every keystroke; cheap local filtering usually does not.

Keep an empty state separate from loading. A loading indicator means the result is not available yet. An empty state means the operation completed and there are no matching rows. Those states lead the user to different next actions.

Decision rule: Use filtering and search deliberately when they make the contract or invariant easier to prove. If they only reduce typing while hiding an assumption, prefer the more explicit design.

4. Pagination

Pagination limits how much data the client must render and move over the network. Use bounded pages or cursors, and preserve filters and sort as the user navigates. If the relevant state lives in the URL, the view can be shared and browser Back and Forward can restore the user's context.

Be explicit about what the page number means when a filter or sort changes. In many designs, changing either one resets the page to the first page because the previous page may no longer exist or may no longer be meaningful. That is a contract decision, not an incidental side effect.

Decision rule: Use pagination deliberately when it makes the contract or invariant easier to prove. If it only reduces typing while hiding an assumption, prefer the more explicit design.

5. Selection and bulk actions

Selection across pages requires a model that survives navigation. You might track only the IDs on the current page, keep an explicit set of selected IDs, or interpret “select all” as all matching records except a set of exclusions. Each model produces different counts, request payloads, and confirmation text.

Do not leave those semantics implicit. A bulk action must also define what happens when a selected row disappears, the filter changes, the request partially fails, or another user changes the same record. The client can present selection and initiate the action, but server-side authorization and validation still own whether the action is allowed.

Decision rule: Use selection and bulk actions deliberately when they make the contract or invariant easier to prove. If they only reduce typing while hiding an assumption, prefer the more explicit design.

6. Responsive and accessible UX

Keyboard-accessible controls, visible focus, text alternatives, and readable loading states are part of the feature. On a narrow screen, a table may need horizontal overflow or an alternate layout, but the alternate presentation still needs to preserve the meaning of headers, rows, actions, and status messages.

Decision rule: Use responsive and accessible UX deliberately when it makes the contract or invariant easier to prove. If it only reduces typing while hiding an assumption, prefer the more explicit design.

Worked example

Consider a timed machine-coding exercise for a data table that must remain readable, accessible, testable, and easy to extend under interview pressure. Begin with a one-sentence requirement. Then list the input and output contracts and map each failure mode to the concept or layer that owns it. The key move is separation: parsing and validation belong at the boundary; domain rules belong in the domain or service layer; persistence rules belong in the database or repository; and presentation rules belong in the client. Mixing them can make a happy-path demo look shorter, but it makes edge cases much harder to reason about.

ts
export async function handleRequest(input: unknown) {
  const command = parseCommand(input);
  const result = await service.execute(command);
  return toHttpResponse(result);
}

The handler gives each step a clear owner. parseCommand turns untrusted input into a command the service can rely on. The service applies the operation's rules, and toHttpResponse translates the result into the client-facing response shape. In a real table flow, the same boundary thinking applies to query parameters, selected IDs, bulk-action requests, and server responses.

Walk through at least four cases: the normal path; an empty or missing value; a duplicate, retry, or concurrent path where that distinction applies; and a dependency failure. For each case, say which layer detects the problem and what the caller observes. For example, malformed pagination input should be rejected at the boundary, while an unavailable orders service should become an appropriate error state for the UI. This is the level of explanation expected in a senior code review or technical interview.

Production perspective

Production correctness is broader than “the code works on my machine.” Ask how the design behaves during deploys, retries, partial failures, stale clients, concurrent requests, malformed data, schema changes, and high-cardinality result sets. Prefer explicit contracts, bounded resource usage, structured errors, and measurable behavior. Optimize only after you can identify the bottleneck or risk with evidence.

When an external dependency is involved, define a timeout and cancellation strategy. When persistence is involved, define transaction and consistency expectations. When the UI displays server data, define loading, empty, error, stale, and success states. When security is involved, assume that the client can be modified and that network input is untrusted. Client-side selection or button visibility is not a substitute for server-side authorization.

Guided lab

Run a 2-hour timed challenge for a server-backed orders table. The table should support search, filters, sorting, pagination, a detail drawer, row selection, one bulk action, loading/error/empty states, responsive behavior, and targeted tests.

Complete the lab with this discipline:

  1. Write the requirement and two non-requirements.
  2. List input, output, and error contracts before implementation.
  3. Implement the smallest correct vertical slice.
  4. Add at least one invalid-input test and one edge-case test.
  5. Instrument or inspect the behavior instead of guessing.
  6. Refactor one hidden assumption into an explicit type, constraint, function, or configuration.
  7. Explain one alternative design and why you did not choose it.
  8. Record a short “what would break at 10× scale?” note.

Edge cases and failure modes

  • Table semantics: test absence, malformed input, duplicates, ordering or concurrency where applicable, and behavior at the smallest and largest credible sizes.
  • Sorting: test absence, malformed input, duplicates, ordering or concurrency where applicable, and behavior at the smallest and largest credible sizes.
  • Filtering and search: test absence, malformed input, duplicates, ordering or concurrency where applicable, and behavior at the smallest and largest credible sizes.
  • Pagination: test absence, malformed input, duplicates, ordering or concurrency where applicable, and behavior at the smallest and largest credible sizes.
  • Selection and bulk actions: test absence, malformed input, duplicates, ordering or concurrency where applicable, and behavior at the smallest and largest credible sizes.

For debugging, begin with the smallest failing case. Inspect the actual value or execution plan, trace the boundary where the invariant first becomes false, and fix the layer that owns the problem rather than adding a downstream patch. In a table, that may mean checking the URL query, the Network request, the server response, the normalized client state, or the rendered DOM in that order.

Common mistakes and debugging

  • Solving the example instead of the requirement: a copied pattern can be syntactically correct but architecturally wrong for the required data volume, interaction model, or API contract.
  • Hiding uncertainty with assertions, broad exception handlers, permissive schemas, or “temporary” any values.
  • Testing only the happy path, and therefore discovering the real contracts only after integration.
  • Optimizing before measuring, or choosing a scalable mechanism without an actual scale requirement.
  • Letting client-side behavior stand in for server-side authorization, validation, or persistence guarantees.

For debugging, reproduce the smallest failing case, inspect the actual value or execution plan, trace the boundary where the invariant first becomes false, and fix the owning layer rather than adding a downstream patch. This keeps a stale response, incorrect selection count, or malformed query from being treated as a rendering problem when the defect began elsewhere.

Interview questions

  1. What problem does Table semantics solve, and what trade-off or failure mode would make you choose a different approach?
  2. What problem does Sorting solve, and what trade-off or failure mode would make you choose a different approach?
  3. What problem does Filtering and search solve, and what trade-off or failure mode would make you choose a different approach?
  4. What problem does Pagination solve, and what trade-off or failure mode would make you choose a different approach?
  5. What problem does Selection and bulk actions solve, and what trade-off or failure mode would make you choose a different approach?

Checkpoint

Without notes, explain Frontend Machine-Coding Challenge: Data Table / Dashboard to another developer in five minutes. Include one invariant, one edge case, one production failure mode, and one alternative design. Then implement a small example without copying the lesson code.

Mastery checklist

  • I can define the core terms precisely.
  • I can choose a design from requirements instead of from habit.
  • I can implement and test the normal path and edge cases.
  • I can explain the runtime, storage, or complexity cost.
  • I can identify which layer owns validation, errors, and recovery.
  • I can compare at least two reasonable alternatives.
  • I can explain how the design changes at larger scale or stricter reliability.

References

Reader page: /machine-coding/lesson/245/frontend-machine-coding-challenge-data-table-dashboard