Skip to content

Instantly share code, notes, and snippets.

@onderceylan
Last active April 26, 2021 18:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save onderceylan/4949d5e071a75276e0de32bd522ee87d to your computer and use it in GitHub Desktop.
Save onderceylan/4949d5e071a75276e0de32bd522ee87d to your computer and use it in GitHub Desktop.
Entity adapter and some of the CUD operations - reducer
import * as fromEvents from '../actions/events.action';
import { createEntityAdapter, EntityAdapter, EntityState } from '@ngrx/entity';
import { Event } from '../../models/event.model';
export interface EventsState extends EntityState<EventEntity> {
loaded: boolean;
loading: boolean;
error: Error;
}
export function sortDescByUpdatedDateTime(a: EventEntity, b: EventEntity) {
return b.data.updatedDateTime - a.data.updatedDateTime;
}
// Note that you can build your custom sort function as above and pass it down
// to your entity adapter to automatically sort ids array based on your sort logic
export const eventEntityAdapter: EntityAdapter<EventEntity> = createEntityAdapter<EventEntity>({
selectId: (event: EventEntity) => event.data.eventId,
sortComparer: sortDescByUpdatedDateTime,
});
export const initialState: EventsState = eventEntityAdapter.getInitialState({
loaded: false,
loading: false,
error: null,
});
export interface EventEntity {
data: Event;
read: boolean;
}
export function eventsReducer(state = initialState, action: fromEvents.EventsActionsUnion): EventsState {
switch (action.type) {
case fromEvents.EventsActionTypes.LoadAllEvents: {
return {
...state,
error: null,
loading: true,
};
}
// You can use one of the ...many operations here, based on your business requirements
// addMany, updateMany and upsertMany are available
case fromEvents.EventsActionTypes.LoadAllEventsSuccess: {
return eventEntityAdapter.upsertMany(action.payload, {
...state,
loading: false,
loaded: true,
});
}
case fromEvents.EventsActionTypes.LoadAllEventsFail: {
return {
...state,
loading: false,
error: action.payload,
};
}
case fromEvents.EventsActionTypes.ClearOldEvents: {
const idsOfexpiredEntities = /* your logic here */;
return eventEntityAdapter.removeMany(idsOfexpiredEntities, state);
}
// Changes object is an object with Partial<T> type of your entity interface
// You can consider it as an object which will be deep merged to your entity
case fromEvents.EventsActionTypes.ReadEvent: {
return eventEntityAdapter.updateOne(
{
id: action.eventId,
changes: {
read: true,
},
},
state,
);
}
// Note that you need to provide an array of Update<T> to the updateMany operation
// UpdateStr<T> = {
// id: string;
// changes: Partial<T>;
// };
case fromEvents.EventsActionTypes.ReadAllEvents: {
return eventEntityAdapter.updateMany(
[...state.ids].map((eventId: string) => ({
id: eventId,
changes: {
read: true,
},
})),
state,
);
}
}
return state;
}
export const getEventsLoading = (state: EventsState) => state.loading;
export const getEventsLoaded = (state: EventsState) => state.loaded;
export const getEventsError = (state: EventsState) => state.error;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment