1. List the authors
A library screen starts with a list. We have an AllAuthors query from the backend, generated into a typed proxy — so the first job is to get its results onto the screen in a table. And because that query is observable, the table will stay current on its own.
-
Render the table.
DataTableForObservableQuerytakes the query proxy, subscribes to it, and renders each result as a row. You describe the columns with the Cratis-ownedColumnmarker. Itsfieldstring must match a property on the generatedAuthorread model:Authors.tsx import { Page } from '@cratis/components/Common';import { DataTableForObservableQuery } from '@cratis/components/DataTables';import { Column } from '@cratis/components/DataTables';import { AllAuthors } from './Authors/Author'; // generated observable query proxyexport const Authors = () => (<Page title='Authors' panel><DataTableForObservableQuery query={AllAuthors} emptyMessage='No authors yet'><Column field='name' header='Name' sortable /></DataTableForObservableQuery></Page>);
That’s the whole screen. The Page wrapper gives you the titled, panelled chrome the rest of the app uses; the table does the rest.
What you didn’t write
Section titled “What you didn’t write”Notice everything that’s absent. There’s no fetch, no useEffect, no loading flag, no useState holding the rows, and — the part that matters most — no subscription code. DataTableForObservableQuery opened the observable for you. The moment something else in the app registers a new author, the backend pushes the new read-model value down, and this table re-renders with the extra row. You’ll see that happen for real in the next chapter, when we add the form.
Keep field names aligned
Section titled “Keep field names aligned”The generated query and its row values are typed, but Column.field is currently a plain string and the compiler does not validate it against the read model. Keep field names aligned with the generated row type and update them when the backend property changes. For custom cells, use Column<Author> with a typed body callback so row-property access is compiler-checked. A misspelled raw field value is a runtime display/configuration error rather than a TypeScript error.
What you built
Section titled “What you built”- A library screen that lists every author in a table,
- bound to the
AllAuthorsquery with no subscription or fetch code, - that will update itself the instant the data behind it changes.
A read-only list isn’t a back office, though — a librarian needs to add authors. Next we’ll give the screen a command. Let’s act on the list →