Angular Store Development Workflow
Use when implementing PlatformVmStore state management for lists, CRUD, complex state, or shared/cached data.
Decision Tree
What kind of state? ├── Component-scoped CRUD list → @Injectable() + providers: [Store] ├── Shared state between components → @Injectable({ providedIn: 'root' }) ├── Form with dependent lookups → @Injectable() + forkJoin for parallel load ├── Cached lookup data → @Injectable({ providedIn: 'root' }) + enableCaching └── Simple component (no store) → Use AppBaseVmComponent instead
Workflow
-
Search existing stores: grep "{Feature}Store" --include="*.ts"
-
Read design system docs (see Read Directives below)
-
Define state interface with all required properties
-
Implement vmConstructor with default state
-
Add selectors via select() , effects via effectSimple() , updaters via updateState()
-
Integrate with component: extend AppBaseVmStoreComponent , provide store
-
Verify checklist below
Key Rules
-
Effects use effectSimple(fn, 'requestKey')
-
second param auto-tracks loading state
-
State updates must be immutable: updateState(state => ({ items: [...state.items, newItem] }))
-
Selectors are memoized via select()
-
return Signal<T>
-
Use tapResponse(success, error) inside effects
-
Component-scoped: providers: [Store] in @Component
-
Singleton cached: @Injectable({ providedIn: 'root' })
- enableCaching
File Location
src/Frontend/apps/{app-name}/src/app/features/{feature}/ ├── {feature}.store.ts └── {feature}.component.ts
⚠️ MUST READ Before Implementation
IMPORTANT: You MUST read these files before writing any code. Do NOT skip.
-
⚠️ MUST READ .claude/skills/shared/angular-design-system.md — hierarchy, platform APIs
-
⚠️ MUST READ .claude/skills/shared/bem-component-examples.md — BEM template examples
-
⚠️ MUST READ .claude/skills/frontend-angular-store/references/store-patterns.md — CRUD, dependent data, caching, integration
-
⚠️ MUST READ target app design system: docs/design-system/06-state-management.md
Anti-Patterns
-
Direct api.subscribe() without effectSimple
-
no loading state tracking
-
this.currentVm().items.push(newItem)
-
mutates state directly
-
Missing providers: [Store] in component decorator
-
Using observerLoadingErrorState inside effectSimple (it handles loading internally)
-
Store as singleton when it should be component-scoped (or vice versa)
Verification Checklist
-
State interface defines all required properties
-
vmConstructor provides default state
-
Effects use effectSimple() with request key
-
Effects use tapResponse() for handling
-
Selectors use select() for memoization
-
State updates are immutable
-
Store provided at correct level (component vs root)
-
Caching configured if needed (enableCaching , cachedStateKeyName )
IMPORTANT Task Planning Notes
-
Always plan and break many small todo tasks
-
Always add a final review todo task to review the works done at the end to find any fix or enhancement needed