---
name: getting-started
description: >
Create an Angular TanStack Table v9 table with injectTable inside injection context, explicit stable tableFeatures and columns, signal-backed data, and FlexRender structural directives or helpers.
metadata:
type: framework
library: '@tanstack/angular-table'
framework: angular
library_version: '9.1.0'
requires:
- '@tanstack/table-core#core'
- '@tanstack/table-core#table-features'
sources:
- 'TanStack/table:docs/framework/angular/guide/migrating.md'
- 'TanStack/table:docs/framework/angular/guide/rendering.md'
- 'TanStack/table:examples/angular/basic-inject-table'
- 'TanStack/table:packages/angular-table/src/index.ts'
---
This skill builds on `@tanstack/table-core#core` and `@tanstack/table-core#table-features`. Read them first for the headless model and explicit features.
## Setup
```ts
import { Component, signal } from '@angular/core'
import { FlexRender, injectTable, tableFeatures } from '@tanstack/angular-table'
type Person = { name: string; age: number }
const features = tableFeatures({})
const columns = [
{ accessorKey: 'name', header: 'Name' },
{ accessorKey: 'age', header: 'Age' },
]
@Component({
selector: 'app-table',
imports: [FlexRender],
template: `
@for (row of table.getRowModel().rows; track row.id) {
@for (cell of row.getAllCells(); track cell.id) {
|
{{
value
}}
|
}
}
`,
})
export class TableComponent {
readonly data = signal([{ name: 'Ada', age: 36 }])
readonly table = injectTable(() => ({ features, columns, data: this.data() }))
}
```
## Core Patterns
### Keep static inputs outside the initializer
`injectTable` reruns its options initializer when a signal read changes. Define features, row-model factories, and columns at module or stable class scope; read only changing values inside.
### Render each content kind correctly
Import `FlexRender` for `*flexRender`, `*flexRenderCell`, `*flexRenderHeader`, and `*flexRenderFooter`. Definitions may yield primitives, `TemplateRef`, component types, or `flexRenderComponent(...)`; Table does not supply markup or CSS.
## Common Mistakes
### CRITICAL Calling injectTable outside DI
Wrong:
```ts
export function makeTable() {
return injectTable(() => ({ features, columns, data }))
}
```
Correct:
```ts
export class TableComponent {
readonly table = injectTable(() => ({ features, columns, data: this.data() }))
}
```
`injectTable` asserts an Angular injection context and registers lifecycle cleanup there.
Source: `packages/angular-table/src/injectTable.ts`
### HIGH Reallocating static options reactively
Wrong:
```ts
injectTable(() => ({
features: tableFeatures({}),
columns: makeColumns(),
data: this.data(),
}))
```
Correct:
```ts
const features = tableFeatures({})
const columns = makeColumns()
injectTable(() => ({ features, columns, data: this.data() }))
```
Every signal change reruns the initializer; rebuilding static inputs invalidates memoized Table work.
Source: `packages/angular-table/src/injectTable.ts`
### HIGH Treating a render function as a component
Wrong:
```ts
cell: () => flexRenderComponent(() => 'value')
```
Correct:
```ts
cell: () => 'value'
```
`flexRenderComponent` wraps an Angular component type; ordinary functions and primitives are handled directly by FlexRender.
Source: `docs/framework/angular/guide/rendering.md`
## API Discovery
Inspect `node_modules/@tanstack/angular-table/dist/types/` for the bundled public API; inspect optional feature APIs in installed `@tanstack/table-core/dist/features/`.