Skip to main contentngrx
NgRx state management for Angular including store, effects, entity adapter, component store, and selectors.
Ir a la instalación Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/a5c-ai/babysitter --skill ngrxEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Más de este repositorio
Reference for querying the Atlas knowledge graph through its MCP tools — the SECONDARY enrichment/comparison layer that adds best-practice context to systems you have ALREADY scanned from your real sources (`az`, repos, dirs). Use when you need to look up nodes, edges, kinds, clusters, stats, or wiki pages in Atlas to compare against your real inventory. (atlas graph, query atlas, atlas mcp, search the graph, graph neighbors, atlas record, atlas kinds, enrichment layer)
Atlas turns your STATED NEED into a real systems atlas by SCANNING your actual sources (Azure via `az`, git repos, local dirs) and process/data mining them, THEN enriching against the Atlas knowledge graph. Use this skill when asked to inventory/map your real systems, scan your cloud + repos + directories, mine the real processes or data they contain, or collect their real constraints/gotchas. (atlas, scan my systems, inventory our azure account, map my repos, real systems atlas, process mining, data mining, collect nuances, system discovery)
assimilate-popular-workflows This skill should be used when the user asks to "find skills in the wild", "assimilate popular workflows", "discover SKILL.md files in repos", "research external skills", "find workflow patterns", "survey the skill landscape", "what skills exist out there", or wants to investigate public repositories for extractable processes, babysitter plugins, and reusable procedural insights. Searches GitHub for SKILL.md files, classifies repos by archetype, and maintains structured research under docs/reference-repos/.
Explorador de archivos
2 archivosOcupaciones relacionadasSOC
Basado en la clasificación ocupacional SOC
| name | ngrx |
| description | NgRx state management for Angular including store, effects, entity adapter, component store, and selectors. |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep |
| graph | {"domains":["domain:web-development"],"specializations":["specialization:web-development"],"skillAreas":["skill-area:application-state-management","skill-area:state-management-testing"],"roles":["role:frontend-engineer"],"topics":["topic:redux-pattern","topic:flux-architecture"]} |
NgRx Skill
Expert assistance for implementing NgRx state management in Angular applications.
Capabilities
- Configure NgRx store with feature states
- Create actions, reducers, and selectors
- Implement effects for side effects
- Use entity adapter for collections
- Apply component store for local state
- Set up NgRx DevTools integration
Usage
Invoke this skill when you need to:
- Implement centralized state management
- Handle complex async workflows
- Manage normalized entity collections
- Debug state changes with DevTools
- Scale Angular application state
Inputs
| Parameter | Type | Required | Description |
|---|
| featureName | string | Yes |
| entityAdapter | boolean | No | Use entity adapter |
| effects | array | No | Effects to create |
| componentStore | boolean | No | Use component store |
Configuration Example
{
"featureName": "users",
"entityAdapter": true,
"effects": ["loadUsers", "createUser", "updateUser"],
"componentStore": false
}
NgRx Patterns
Actions
import { createActionGroup, emptyProps, props } from '@ngrx/store';
export const UsersActions = createActionGroup({
source: 'Users',
events: {
'Load Users': emptyProps(),
'Load Users Success': props<{ users: User[] }>(),
'Load Users Failure': props<{ error: string }>(),
'Create User': props<{ user: CreateUserDto }>(),
'Create User Success': props<{ user: User }>(),
'Create User Failure': props<{ error: string }>(),
'Update User': props<{ id: string; changes: Partial<User> }>(),
'Update User Success': props<{ user: User }>(),
'Update User Failure': props<{ error: string }>(),
'Delete User': props<{ id: string }>(),
'Delete User Success': props<{ id: string }>(),
'Delete User Failure': props<{ error: string }>(),
'Select User': props<{ id: string | null }>(),
},
});
Reducer with Entity Adapter
import { createReducer, on } from '@ngrx/store';
import { createEntityAdapter, EntityState } from '@ngrx/entity';
import { UsersActions } from './users.actions';
export interface User {
id: string;
name: string;
email: string;
}
export interface UsersState extends EntityState<User> {
selectedId: string | null;
loading: boolean;
error: string | null;
}
export const usersAdapter = createEntityAdapter<User>({
selectId: (user) => user.id,
sortComparer: (a, b) => a.name.localeCompare(b.name),
});
const initialState: UsersState = usersAdapter.getInitialState({
selectedId: null,
loading: false,
error: null,
});
export const usersReducer = createReducer(
initialState,
on(UsersActions.loadUsers, (state) => ({
...state,
loading: true,
error: null,
})),
on(UsersActions.loadUsersSuccess, (state, { users }) =>
usersAdapter.setAll(users, { ...state, loading: false })
),
on(UsersActions.loadUsersFailure, (state, { error }) => ({
...state,
loading: false,
error,
})),
on(UsersActions.createUserSuccess, (state, { user }) =>
usersAdapter.addOne(user, state)
),
on(UsersActions.updateUserSuccess, (state, { user }) =>
usersAdapter.updateOne({ id: user.id, changes: user }, state)
),
on(UsersActions.deleteUserSuccess, (state, { id }) =>
usersAdapter.removeOne(id, state)
),
on(UsersActions.selectUser, (state, { id }) => ({
...state,
selectedId: id,
}))
);
Selectors
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { usersAdapter, UsersState } from './users.reducer';
export const selectUsersState = createFeatureSelector<UsersState>('users');
const { selectAll, selectEntities, selectIds, selectTotal } =
usersAdapter.getSelectors();
export const selectAllUsers = createSelector(selectUsersState, selectAll);
export const selectUserEntities = createSelector(
selectUsersState,
selectEntities
);
export const selectUsersLoading = createSelector(
selectUsersState,
(state) => state.loading
);
export const selectUsersError = createSelector(
selectUsersState,
(state) => state.error
);
export const selectSelectedUserId = createSelector(
selectUsersState,
(state) => state.selectedId
);
export const selectSelectedUser = createSelector(
selectUserEntities,
selectSelectedUserId,
(entities, selectedId) => (selectedId ? entities[selectedId] : null)
);
export const selectUsersCount = createSelector(selectUsersState, selectTotal);
Effects
import { Injectable, inject } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { catchError, map, mergeMap, switchMap, of } from 'rxjs';
import { UsersActions } from './users.actions';
import { UsersService } from '../../services/users.service';
@Injectable()
export class UsersEffects {
private actions$ = inject(Actions);
private usersService = inject(UsersService);
loadUsers$ = createEffect(() =>
this.actions$.pipe(
ofType(UsersActions.loadUsers),
switchMap(() =>
this.usersService.getAll().pipe(
map((users) => UsersActions.loadUsersSuccess({ users })),
catchError((error) =>
of(UsersActions.loadUsersFailure({ error: error.message }))
)
)
)
)
);
createUser$ = createEffect(() =>
this.actions$.pipe(
ofType(UsersActions.createUser),
mergeMap(({ user }) =>
this.usersService.create(user).pipe(
map((user) => UsersActions.createUserSuccess({ user })),
catchError((error) =>
of(UsersActions.createUserFailure({ error: error.message }))
)
)
)
)
);
updateUser$ = createEffect(() =>
this.actions$.pipe(
ofType(UsersActions.updateUser),
mergeMap(({ id, changes }) =>
this.usersService.update(id, changes).pipe(
map((user) => UsersActions.updateUserSuccess({ user })),
catchError((error) =>
of(UsersActions.updateUserFailure({ error: error.message }))
)
)
)
)
);
deleteUser$ = createEffect(() =>
this.actions$.pipe(
ofType(UsersActions.deleteUser),
mergeMap(({ id }) =>
this.usersService.delete(id).pipe(
map(() => UsersActions.deleteUserSuccess({ id })),
catchError((error) =>
of(UsersActions.deleteUserFailure({ error: error.message }))
)
)
)
)
);
}
Component Store (Local State)
import { Injectable } from '@angular/core';
import { ComponentStore } from '@ngrx/component-store';
import { switchMap, tap, catchError, EMPTY } from 'rxjs';
interface UserListState {
users: User[];
loading: boolean;
filter: string;
}
@Injectable()
export class UserListStore extends ComponentStore<UserListState> {
constructor(private usersService: UsersService) {
super({
users: [],
loading: false,
filter: '',
});
}
readonly users$ = this.select((state) => state.users);
readonly loading$ = this.select((state) => state.loading);
readonly filter$ = this.select((state) => state.filter);
readonly filteredUsers$ = this.select(
this.users$,
this.filter$,
(users, filter) =>
users.filter((u) => u.name.toLowerCase().includes(filter.toLowerCase()))
);
readonly setFilter = this.updater((state, filter: string) => ({
...state,
filter,
}));
readonly loadUsers = this.effect((trigger$) =>
trigger$.pipe(
tap(() => this.patchState({ loading: true })),
switchMap(() =>
this.usersService.getAll().pipe(
tap((users) => this.patchState({ users, loading: false })),
catchError(() => {
this.patchState({ loading: false });
return EMPTY;
})
)
)
)
);
}
Store Setup
import { ApplicationConfig } from '@angular/core';
import { provideStore } from '@ngrx/store';
import { provideEffects } from '@ngrx/effects';
import { provideStoreDevtools } from '@ngrx/store-devtools';
import { usersReducer } from './store/users/users.reducer';
import { UsersEffects } from './store/users/users.effects';
export const appConfig: ApplicationConfig = {
providers: [
provideStore({
users: usersReducer,
}),
provideEffects(UsersEffects),
provideStoreDevtools({
maxAge: 25,
logOnly: false,
}),
],
};
Best Practices
- Use createActionGroup for related actions
- Leverage entity adapter for collections
- Keep effects focused on single responsibilities
- Use component store for local state
- Create granular selectors for performance
Target Processes
- angular-enterprise-development
- state-management-setup
- complex-data-flows
- enterprise-architecture