@ngrxs/states
v18.0.0
Published
An NGRX router store with actions and router selectors for easier development
Downloads
19
Readme
@ngrxs/states
@ngrxs/states
library that provide a common state objects that include selecting, loading and saving metadata.
Installation
npm install --save @ngrxs/states
Import and use
SharedState
in a state:import { SharedState, adapter } from '@ngrxs/states'; export type UsersState = SharedState<Users[], number>; export const initialState: UsersState = adapter.getInitialState<User[], number>([]);
Usage
@ngrxs/states
provides shared state to hold loaded, loading, saving information and selectors for it.
// filename: users.reducer.ts
import { adapter, SharedState } from '@ngrxs/states';
import { createReducer, on } from '@ngrx/store';
import * as actions from './users.actions';
import { User } from '../models/user';
export type UsersState = SharedState<User[], number>;
export const initialState: UsersState = adapter.getInitialState<User[], number>([]);
export const setUser = adapter.createArraySetter((user: User) => user.id);
export const usersReducer = createReducer(
initialState,
on(actions.getAllUsers, state => adapter.loading(state, state.entities)),
on(actions.allUsersLoaded, (state, { users }) => adapter.loaded(state, users)),
on(actions.allUsersLoadFail, (state, { error }) => adapter.loadFail(state, error)),
on(actions.editUser, state => adapter.saving(state)),
on(actions.editUserSuccess, (state, { user }) => adapter.saved(state, setUser(state, user))),
on(actions.editUserFailed, (state, { error }) => adapter.saveFail(state, error))
);
adapter
Methods
adapter.getInitialLoadableState<T>(value: T)
{
entities: value,
loading: {
error: null,
loading: false
},
loaded: false
}
adapter.getInitialState<T>(value: T)
{
entities: value,
loading: {
error: null,
loading: false
},
loaded: false,
saving: {
error: null,
loading: false
},
selectedId: null
}
adapter.select(state: TState, selectedId: TId) => ({ ...state, selectedId })
adapter.loading(state: TState, entities: TData) => ({ ...state, entities, loading: { loading: true, error: null } })
adapter.loaded(state: TState, entities: TData) => ({ ...state, entities, loading: { loading: false, error: null }, loaded: true })
List of Selectors
| Selectors | Usage | | ---------------- | --------------------------------- | | selectEntities | Select the state entities | | selectSaveState | Select the saving state | | selectLoadState | Select the loading state | | selectLoaded | Select the loaded value | | selectSelectedId | Select the selected id |
Interfaces
@ngrxs/states
exposes interfaces.
LoadableState
{
error: string | null;
loading: boolean;
}
SharedLoadableState<TData>
{
readonly entities: TData;
readonly loading: LoadableState;
readonly loaded: boolean;
}
SharedState<TData, TId extends number | string | null>
{
readonly entities: TData;
readonly loading: LoadableState;
readonly loaded: boolean;
readonly saving: LoadableState;
readonly selectedId: TId;
}
fetch
method
a method fetch
fetching state data from service.
fetch(options: {
id?: (action: TAction) => PropertyKey // (optional) get the unique id to group results.
ttl?: number // (optional) when provided it caches the result. ttl is in milliseconds.
fetch: (action: TAction) => Observable<TData>; // the fetch action
mapFn: (data: TData) => Action; // the action mapper function
errorFn: (error: Error) => Action; // the error mapper function
})
Example
import { fetch } from '@ngrxs/states';
@Injectable()
export class UsersEffects {
readonly #actions$ = inject(Actions);
readonly #service = inject(UsersService);
loadUsers$ = createEffect(() =>
this.#actions$.pipe(
ofType(actions.getAllUsers),
fetch({
fetch: () => this.#service.getAllUsers(),
mapFn: payload => actions.allUsersLoaded({ users: payload }),
errorFn: error => actions.allUsersLoadFail({ error }),
})
)
);
getUserById$ = createEffect(() =>
this.#actions$.pipe(
ofType(actions.getByUserId),
fetch({
id: ({ id }) => `user_${id}`,
ttl: 5_000,
fetch: ({ id }) => this.#service.getUserById(id),
mapFn: user => actions.userLoaded({ user }),
errorFn: error => actions.userLoadFail({ error }),
})
)
);
}