Collection
Eager collection class for one-to-many relationships. Holds array of loaded models.
Import
import { Collection } from '@gluonic/client'Class Signature
class Collection<T> {
// Constructor
constructor(items?: T[])
// Properties
get length(): number
// Methods
at(index: number): T | undefined
map<U>(fn: (item: T, i: number) => U): U[]
forEach(fn: (item: T, i: number) => void): void
filter(fn: (item: T, i: number) => boolean): T[]
find(fn: (item: T, i: number) => boolean): T | undefined
toArray(): T[]
push(item: T): number
}Note: Collection is eager - all items are loaded immediately. For lazy loading, use LazyCollection.
Constructor
constructor(items?: T[])Create a collection with optional initial items.
Parameters:
| Parameter | Type | Description |
|---|---|---|
items | T[] | Optional initial array |
Example:
// Empty collection
const comments = new Collection<Comment>()
// With initial items
const comments = new Collection<Comment>([comment1, comment2])Properties
length
get length(): numberNumber of items in the collection.
Returns: number - Count of items
Reactive: Updates when items are added/removed
Example:
const TaskList = observer(({ project }) => {
return <div>{project.tasks.length} tasks</div>
})Methods
at()
at(index: number): T | undefinedGet item at specific index.
Parameters:
| Parameter | Type | Description |
|---|---|---|
index | number | Zero-based index |
Returns: T | undefined - Item at index or undefined
Example:
const firstTask = project.tasks.at(0)
const lastTask = project.tasks.at(-1) // Negative index from endmap()
map<U>(fn: (item: T, i: number) => U): U[]Transform each item.
Parameters:
| Parameter | Type | Description |
|---|---|---|
fn | (item, i) => U | Transform function |
Returns: U[] - Transformed array
Example:
const TaskList = observer(({ project }) => {
return (
<div>
{project.tasks.map((task, i) => (
<TaskCard key={task.id} task={task} index={i} />
))}
</div>
)
})forEach()
forEach(fn: (item: T, i: number) => void): voidIterate over each item.
Parameters:
| Parameter | Type | Description |
|---|---|---|
fn | (item, i) => void | Callback for each item |
Example:
project.tasks.forEach((task, i) => {
console.log(`${i}: ${task.title}`)
})filter()
filter(fn: (item: T, i: number) => boolean): T[]Get items matching predicate.
Parameters:
| Parameter | Type | Description |
|---|---|---|
fn | (item, i) => boolean | Filter function |
Returns: T[] - Filtered array
Example:
const DoneTaskList = observer(({ project }) => {
const doneTasks = project.tasks.filter(task => task.done)
return <div>{doneTasks.length} done</div>
})find()
find(fn: (item: T, i: number) => boolean): T | undefinedFind first item matching predicate.
Parameters:
| Parameter | Type | Description |
|---|---|---|
fn | (item, i) => boolean | Search function |
Returns: T | undefined - First match or undefined
Example:
const urgentTask = project.tasks.find(task => task.priority === 'urgent')toArray()
toArray(): T[]Get copy of items as plain array.
Returns: T[] - Copy of items
Example:
const taskArray = project.tasks.toArray()
console.log(taskArray.length)push()
push(item: T): numberAdd item to collection.
Parameters:
| Parameter | Type | Description |
|---|---|---|
item | T | Item to add |
Returns: number - New length
Example:
project.tasks.push(newTask)Usage
In Model Definitions
Use Collection for eager relationships (all items loaded immediately):
@ClientModel('project')
export class Project extends Model {
@Property()
id = crypto.randomUUID()
@Property()
title = ''
// Collection (eager) - all tasks loaded immediately
@OneToMany('task', 'project')
tasks = new Collection<Task>()
}Runtime: At runtime, @OneToMany decorator transforms this to LazyCollection<Task> for lazy loading. The clean type signature Collection<Task> is preserved for TypeScript.
In Components
const ProjectDetail = observer(({ project }) => {
return (
<div>
<h1>{project.title}</h1>
<p>{project.tasks.length} tasks</p>
<ul>
{project.tasks.map(task => (
<li key={task.id}>{task.title}</li>
))}
</ul>
</div>
)
})Collection vs LazyCollection
| Feature | Collection | LazyCollection |
|---|---|---|
| Loading | Eager (all items immediately) | Lazy (loads when accessed) |
| Initial state | Items provided in constructor | Empty until hydrated |
| Network | No automatic fetching | Auto-fetches on first access |
| Use case | Small, pre-loaded sets | Relationships, large sets |
Recommendation: Use LazyCollection for relationships (default behavior with decorators).
Examples
Filtering
const ActiveTasks = observer(({ project }) => {
const activeTasks = project.tasks.filter(task => !task.done)
return (
<div>
<h2>Active Tasks ({activeTasks.length})</h2>
{activeTasks.map(task => (
<TaskCard key={task.id} task={task} />
))}
</div>
)
})Sorting
const SortedTasks = observer(({ project }) => {
const sortedTasks = project.tasks
.toArray()
.sort((a, b) => a.title.localeCompare(b.title))
return (
<ul>
{sortedTasks.map(task => (
<li key={task.id}>{task.title}</li>
))}
</ul>
)
})Computed Stats
const TaskStats = observer(({ project }) => {
const total = project.tasks.length
const done = project.tasks.filter(t => t.done).length
const progress = total > 0 ? (done / total) * 100 : 0
return (
<div>
<p>{done} of {total} complete</p>
<ProgressBar value={progress} />
</div>
)
})See Also
- LazyCollection - Lazy-loading collection (recommended for relationships)
- Model - Model base class
- Decorators - @OneToMany decorator
- Relationships Guide - Complete relationship guide