signals-state-management
Manejo de estado con signals y el patrón de contexto global de compañía. Usa esto cuando trabajes con estado local, estado derivado, o necesites acceder a la compañía seleccionada globalmente.
- Category: discovered
- Tags: github, community
- Version: 1.0.0
- Author: walid
- Downloads: 0
- Updated: 2025-11-22
Download the latest version (v1.0.0) from this page.
SKILL.md
---
description: Manejo de estado con signals y el patrón de contexto global de compañía. Usa esto cuando trabajes con estado local, estado derivado, o necesites acceder a la compañía seleccionada globalmente.
---
# Angular State Management with Signals 📊
## Signal-Based State
Use signals for all local component state:
```typescript
export class MyComponent {
// Local state
count = signal(0);
name = signal('');
items = signal<Item[]>([]);
}
```
## Derived State with computed()
Use `computed()` for derived state - it's reactive and memoized:
```typescript
export class MyComponent {
items = signal<Item[]>([]);
searchTerm = signal('');
// Automatically recalculates when items or searchTerm change
filteredItems = computed(() => {
return this.items().filter(item =>
item.name.includes(this.searchTerm())
);
});
itemCount = computed(() => this.items().length);
}
```
## State Transformations
- Keep state transformations pure and predictable
- **DO NOT** use `mutate` on signals
- Use `update` or `set` instead:
```typescript
// ✅ Correct
this.items.update(items => [...items, newItem]);
this.count.set(10);
// ❌ Avoid
this.items.mutate(items => items.push(newItem));
```
## API Data Handling
**DO NOT** transform data received from endpoints:
- Always use the data structure provided by the API
- Let the backend define the data shape
- If transformation is needed, do it in the service layer, not in components
## Global Company Context Pattern 🏢
**ALWAYS** use the `CompanyContextService` for accessing the selected company across the application.
### Service Location
`src/app/core/services/company-context.service.ts`
### Key Features
- Signal-based global state for selected company
- Automatic localStorage persistence
- Auto-recovery on page refresh
- Type-safe company context
### Usage in Feature Modules
```typescript
import { CompanyContextService } from '@core/services';
export class MyFeatureListComponent {
private companyContext = inject(CompanyContextService);
selectedCompany = this.companyContext.selectedCompany;
constructor() {
// React to company changes automatically
effect(() => {
const company = this.selectedCompany();
if (company) {
console.log('🏢 Company changed:', company);
this.currentPage.set(1);
this.loadData();
}
});
}
loadData() {
const company = this.selectedCompany();
if (!company) {
console.warn('⚠️ No company selected');
return;
}
// Use company.companyId for API calls
this.myService.getData(company.companyId, this.currentPage(), this.pageSize())
.subscribe({...});
}
}
```
### CompanyContext Interface
```typescript
interface CompanyContext {
companyId: number;
companyName: string;
}
```
### Best Practices
- ✅ **ALWAYS** check if company exists before making API calls
- ✅ Use `effect()` to automatically reload data when company changes
- ✅ Reset pagination when company changes (set currentPage to 1)
- ✅ Access via `selectedCompany()` signal - it's readonly
- ❌ **NEVER** store company ID in local component state
- ❌ **NEVER** pass company ID through route params for this purpose
## State Management Principles
1. **Single Source of Truth**: Don't duplicate state
2. **Reactive by Default**: Use signals and computed for reactivity
3. **Immutable Updates**: Always create new references when updating
4. **Predictable**: State changes should be easy to trace
5. **Type-Safe**: Always type your signals properly