Skip to main content ホーム クリエイター tanstack db angular-db
angular-db Angular bindings for TanStack DB. injectLiveQuery inject function with Angular signals (Signal<T>) for all return values. Reactive params pattern ({ params: () => T, query: ({ params, q }) => QueryBuilder }) for dynamic queries. Must be called in injection context. Angular 17+ control flow (@if, @for) and signal inputs supported. Import from @tanstack/angular-db (re-exports all of @tanstack/db).
インストールへ移動 Skills Marketplace コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/TanStack/db --skill angular-dbコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中...
Creating typed collections with createCollection. Adapter selection: queryCollectionOptions (REST/TanStack Query), electricCollectionOptions (ElectricSQL real-time sync), powerSyncCollectionOptions (PowerSync SQLite), rxdbCollectionOptions (RxDB), trailBaseCollectionOptions (TrailBase), localOnlyCollectionOptions, localStorageCollectionOptions. CollectionConfig options: getKey, schema, sync, gcTime, autoIndex (default off), defaultIndexType, syncMode (eager/on-demand, plus progressive for Electric). StandardSchema validation with Zod/Valibot/ArkType. Collection lifecycle (idle/loading/ready/error). Adapter-specific sync patterns including Electric txid tracking, Query direct writes, Query initial data and scoped factories, and PowerSync query-driven sync with onLoad/onLoadSubset hooks.
Building custom collection adapters for new backends. SyncConfig interface: sync function receiving begin, write, commit, markReady, truncate, metadata primitives and returning cleanup, loadSubset, and optional unloadSubset handlers. ChangeMessage format (insert, update, delete). On-demand LoadSubsetOptions (where, orderBy, limit, offset, cursor). Expression parsing: parseWhereExpression, parseOrderByExpression, extractSimpleComparisons, parseLoadSubsetOptions. Collection options creator pattern. rowUpdateMode (partial vs full). Subscription lifecycle and cleanup functions. Persisted sync metadata API (metadata.row and metadata.collection) for storing per-row and per-collection adapter state.
Query builder fluent API: from, where, join, leftJoin, rightJoin, innerJoin, fullJoin, select, fn.select, groupBy, having, orderBy, limit, offset, distinct, findOne. Operators: eq, gt, gte, lt, lte, like, ilike, inArray, isNull, isUndefined, and, or, not. Aggregates: count, sum, avg, min, max. String functions: upper, lower, length, concat. Utility: coalesce, caseWhen. Math: add, subtract, multiply, divide. $selected namespace. createLiveQueryCollection. Derived collections. Predicate push-down. Incremental view maintenance via differential dataflow (d2ts). Virtual properties ($synced, $origin, $key, $collectionId). Includes subqueries for hierarchical data. Collection, toArray, materialize, and concat(toArray(...)) include modes. queryOnce for one-shot queries. createEffect for reactive side effects (onEnter, onUpdate, onExit, onBatch).
name angular-db description Angular bindings for TanStack DB. injectLiveQuery inject function with Angular signals (Signal<T>) for all return values. Reactive params pattern ({ params: () => T, query: ({ params, q }) => QueryBuilder }) for dynamic queries. Must be called in injection context. Angular 17+ control flow (@if, @for) and signal inputs supported. Import from @tanstack/angular-db (re-exports all of @tanstack/db).
type framework library db framework angular library_version 0.6.17 requires ["db-core"] sources ["TanStack/db:docs/framework/angular/overview.md","TanStack/db:packages/angular-db/src/index.ts"]
This skill builds on db-core. Read it first for collection setup, query builder, and mutation patterns.
TanStack DB — Angular
Setup
import { Component } from '@angular/core'
import { injectLiveQuery, eq, not } from '@tanstack/angular-db'
@Component ({
selector : 'app-todo-list' ,
standalone : true ,
template : `
@if (query.isLoading()) {
<div>Loading...</div>
} @else {
<ul>
@for (todo of query.data(); track todo.id) {
<li>{{ todo.text }}</li>
}
</ul>
}
` ,
})
export class TodoListComponent {
query = injectLiveQuery ((q ) =>
q
.from ({ todos : todosCollection })
.where (({ todos } ) => not (todos.completed ))
.orderBy (({ todos } ) => todos.created_at , 'asc' ),
)
}
@tanstack/angular-db re-exports everything from @tanstack/db.
Inject Function
injectLiveQuery
Returns an object with Angular Signal<T> properties — call with () in templates:
const query = injectLiveQuery ((q ) => q. ({ : todoCollection }))
query = ({
: ({ : . () }),
:
q
. ({ : todoCollection })
. ( (todo. , params. )),
})
query = ({
: q. ({ : todoCollection }),
: ,
})
query = (preloadedCollection)
query = ({
: ({ : . () }),
: {
(!params. )
q
. ({ : todoCollection })
. ( (todo. , params. ))
},
})
from
todo
const
injectLiveQuery
params
() =>
minPriority
this
minPriority
query
({ params, q } ) =>
from
todo
where
({ todo } ) =>
gt
priority
minPriority
const
injectLiveQuery
query
(q ) =>
from
todo
gcTime
60000
const
injectLiveQuery
const
injectLiveQuery
params
() =>
userId
this
userId
query
({ params, q } ) =>
if
userId
return
undefined
return
from
todo
where
({ todo } ) =>
eq
userId
userId
A bare { query } config defaults to startSync: true and gcTime: 0, like
the query-function overload. Explicit values in the config override those
defaults.
Angular-Specific Patterns
Reactive params with signals @Component ({
selector : 'app-filtered-todos' ,
standalone : true ,
template : `<div>{{ query.data().length }} todos</div>` ,
})
export class FilteredTodosComponent {
minPriority = signal (5 )
query = injectLiveQuery ({
params : () => ({ minPriority : this .minPriority () }),
query : ({ params, q } ) =>
q
.from ({ todos : todosCollection })
.where (({ todos } ) => gt (todos.priority , params.minPriority )),
})
}
When params() return value changes, the previous collection is disposed and a new query is created.
Signal inputs (Angular 17+) @Component ({
selector : 'app-user-todos' ,
standalone : true ,
template : `<div>{{ query.data().length }} todos</div>` ,
})
export class UserTodosComponent {
userId = input.required <number >()
query = injectLiveQuery ({
params : () => ({ userId : this .userId () }),
query : ({ params, q } ) =>
q
.from ({ todo : todoCollection })
.where (({ todo } ) => eq (todo.userId , params.userId )),
})
}
Legacy @Input (Angular 16) export class UserTodosComponent {
@Input ({ required : true }) userId!: number
query = injectLiveQuery ({
params : () => ({ userId : this .userId }),
query : ({ params, q } ) =>
q
.from ({ todo : todoCollection })
.where (({ todo } ) => eq (todo.userId , params.userId )),
})
}
Template syntax Angular 17+ control flow:
@if (query.isLoading()) {
<div > Loading...</div >
} @else { @for (todo of query.data(); track todo.id) {
<li > {{ todo.text }}</li >
} }
Angular 16 structural directives:
<div *ngIf ="query.isLoading()" > Loading...</div >
<li *ngFor ="let todo of query.data(); trackBy: trackById" > {{ todo.text }}</li >
Includes (Hierarchical Data) When a query uses includes (subqueries in select), each child field is a live Collection by default. Subscribe to it with injectLiveQuery in a child component:
@Component ({
selector : 'app-project-list' ,
standalone : true ,
imports : [IssueListComponent ],
template : `
@for (project of query.data(); track project.id) {
<div>
{{ project.name }}
<app-issue-list [issuesCollection]="project.issues" />
</div>
}
` ,
})
export class ProjectListComponent {
query = injectLiveQuery ((q ) =>
q.from ({ p : projectsCollection }).select (({ p } ) => ({
id : p.id ,
name : p.name ,
issues : q
.from ({ i : issuesCollection })
.where (({ i } ) => eq (i.projectId , p.id ))
.select (({ i } ) => ({ id : i.id , title : i.title })),
})),
)
}
@Component ({
selector : 'app-issue-list' ,
standalone : true ,
template : `
@for (issue of query.data(); track issue.id) {
<li>{{ issue.title }}</li>
}
` ,
})
export class IssueListComponent {
issuesCollection = input.required <Collection >()
query = injectLiveQuery (this .issuesCollection ())
}
With toArray(), child results are plain arrays and the parent re-emits on child changes:
import { toArray, eq } from '@tanstack/angular-db'
query = injectLiveQuery ((q ) =>
q.from ({ p : projectsCollection }).select (({ p } ) => ({
id : p.id ,
name : p.name ,
issues : toArray (
q
.from ({ i : issuesCollection })
.where (({ i } ) => eq (i.projectId , p.id ))
.select (({ i } ) => ({ id : i.id , title : i.title })),
),
})),
)
See db-core/live-queries/SKILL.md for full includes rules (correlation conditions, nested includes, aggregates).
Common Mistakes
CRITICAL Using injectLiveQuery outside injection context export class TodoComponent {
ngOnInit ( ) {
this .query = injectLiveQuery ((q ) => q.from ({ todo : todoCollection }))
}
}
export class TodoComponent {
query = injectLiveQuery ((q ) => q.from ({ todo : todoCollection }))
}
injectLiveQuery calls assertInInjectionContext internally — it must be called during construction (field initializer or constructor), not in lifecycle hooks.
Source: packages/angular-db/src/index.ts
HIGH Using query function for reactive values instead of params export class FilteredComponent {
status = signal ('active' )
query = injectLiveQuery ((q ) =>
q
.from ({ todo : todoCollection })
.where (({ todo } ) => eq (todo.status , this .status ())),
)
}
export class FilteredComponent {
status = signal ('active' )
query = injectLiveQuery ({
params : () => ({ status : this .status () }),
query : ({ params, q } ) =>
q
.from ({ todo : todoCollection })
.where (({ todo } ) => eq (todo.status , params.status )),
})
}
The plain query function overload does not track Angular signal reads. Use the params pattern to make reactive values trigger query re-creation.
Source: packages/angular-db/src/index.ts
MEDIUM Forgetting to call signals in templates <div > {{ query.data.length }}</div >
<div > {{ query.data().length }}</div >
All return values are Angular signals. Without (), you get the signal object, not the value.
See also: db-core/live-queries/SKILL.md — for query builder API.
See also: db-core/mutations-optimistic/SKILL.md — for mutation patterns.