BaseCollection
The BaseCollection class is the foundation for creating and handling array of data models in the EncolaJS Hydrator library. It provides a robust system for handling, transforming, and serializing data with a focus on extensibility and type safety.
Adding Items
The BaseCollection prevents duplicates based on item IDs:
// Add a single item
products.add({ id: 4, name: 'Headphones', price: 150 });
// Try to add a duplicate (will be ignored)
products.add({ id: 1, name: 'Duplicate Laptop', price: 999 });
// Add multiple items with push
products.push(
{ id: 5, name: 'Mouse', price: 50 },
{ id: 6, name: 'Keyboard', price: 80 }
);
// Add items at the beginning
products.unshift({ id: 7, name: 'Monitor', price: 300 });Removing Items
// Remove by ID
products.remove(1); // Removes the item with id=1
// Remove by reference
const item = products[0];
products.remove(item);Filtering and Finding
// Filter by property value
const electronics = products.filterBy('category', 'electronics');
// Filter with a callback function
const expensive = products.filterBy(product => product.price > 500);
// Filter in place (modifies original collection)
products.filterBy('category', 'electronics', true);
// Find a single item by property
const desk = products.findBy('name', 'Desk');
// Find with a callback
const mostExpensive = products.findBy(product => product.price > 500);Sorting
// Sort by property (ascending)
const byPrice = products.sortBy('price');
// Sort by property (descending)
const byPriceDesc = products.sortBy('price', 'desc');
// Sort with a custom function
const byNameLength = products.sortBy((a, b) => a.name.length - b.name.length);
// Sort in place
products.sortBy('price', 'asc', true);Aggregation Methods
// Calculate sum
const totalPrice = products.sum('price');
const weightedPrice = products.sum(item => item.price * item.quantity);
// Find minimum value
const cheapestPrice = products.min('price');
// Find maximum value
const mostExpensive = products.max('price');
// Calculate average
const avgPrice = products.avg('price');Grouping
// Group by category
const byCategory = products.groupBy('category');
console.log(byCategory.electronics); // Array of electronics
console.log(byCategory.furniture); // Array of furniture
// Group with a custom function
const byPriceRange = products.groupBy(item => {
if (item.price < 100) return 'budget';
if (item.price < 500) return 'mid-range';
return 'premium';
});Transformation Methods
// Convert to plain array
const array = products.toArray();
// Get first N items
const topThree = products.head(3);
// Get last N items
const lastTwo = products.tail(2);
// Organize into rows
const rows = products.toRows(2); // [[item1, item2], [item3, item4], ...]
// Organize into columns
const columns = products.toColumns(3); // [[item1, item4, ...], [item2, item5, ...], [item3, item6, ...]]
// Regular array map method
const names = products.map(item => item.name);JSON Serialization
// Convert all items to plain objects
const json = products.toJSON();
console.log(JSON.stringify(json)); // For sending to an APIDeep Cloning
// Create a deep copy of the collection with all items cloned
const copy = products.clone();
// Modify the copy without affecting the original
copy[0].name = 'Modified Name';
console.log(products[0].name); // Original name unchangedTypeScript Integration
// Define item type
interface Product {
id: number;
name: string;
price: number;
category: string;
}
// Create a typed collection
class ProductCollection extends BaseCollection<Product> {
constructor(items: Product[] = []) {
super(items, (item: any) => {
if (item instanceof ProductModel) {
return item;
}
return new ProductModel(item);
});
}
// Methods are properly typed
findByCategory(category: string): ProductCollection {
return this.filterBy('category', category) as ProductCollection;
}
}Native Array Methods
BaseCollection extends Array, so all native array methods are available:
// Using native array methods
products.forEach(item => console.log(item.name));
const filtered = products.filter(item => item.price > 100);
const total = products.reduce((sum, item) => sum + item.price, 0);
const someExpensive = products.some(item => item.price > 1000);
const allInStock = products.every(item => item.inStock);
// Array manipulation methods with proper type casting
const sliced = products.slice(1, 3); // Returns a new BaseCollection
const spliced = products.splice(1, 2, newItem1, newItem2); // Casts new itemsWhy Use BaseCollection?
Rich API - BaseCollection provides a rich, fluent API for working with collections of items, far beyond what native Arrays offer.
Type Casting - Items are automatically cast to the correct type, ensuring consistency within the collection.
ID-Based Operations - BaseCollection can prevent duplicates and perform operations based on item IDs.
Consistent Interface - Collections derived from BaseCollection share a common API, making your code more predictable.
Chainable Methods - Many methods return a new collection, allowing for method chaining:
const result = products
.filterBy('category', 'electronics')
.sortBy('price', 'desc')
.head(3);