DEV Community

Alfredo Perez
Alfredo Perez

Posted on

2 1

NGRX Workshop Notes - Entity

  • Working with collections should be fast
  • Collections are very common
  • @ngrx/entity provides a common set of basic operations
  • @ngrx/entity provides a common set of basic state derivations

How to add @ngrx /entity

  • Start by creating a state that extends the entityState
// From:

// export interface State {
//     collection: BookModel[];
//     activeBookId: string | null;
// }


// To:
export interface State extends EntityState<BookModel> {

    activeBookId: string | null;
}
Enter fullscreen mode Exit fullscreen mode
  • Create an adapter and define the initial state with it.

Note that the collection is no longer needed

// From:

// export const initialState: State = {
//     collection: [],
//     activeBookId: null
// };

// To:
const adapter = createEntityAdapter<BookModel>();

export const initialState: State = adapter.getInitialState({
    activeBookId: null
});
Enter fullscreen mode Exit fullscreen mode
  • Out of the box, it uses the 'id' as the id, but we can also specify custom id and comparer.
const adapter = createEntityAdapter<BookModel>({
    selectId: (model: BookModel) => model.name,
    sortComparer:(a:BookModel,b:BookModel)=> a.name.localeCompare(b.name)
});
Enter fullscreen mode Exit fullscreen mode
  • Refactor the reducers to use the entity adapter
    // on(BooksApiActions.bookCreated, (state, action) => {
    //     return {
    //         collection: createBook(state.collection, action.book),
    //         activeBookId: null
    //     };
    // }),
    on(BooksApiActions.bookCreated, (state, action) => {
        return adapter.addOne(action.book, {
            ...state,
            activeBookId: null
        })
    }),

    // on(BooksApiActions.bookUpdated, (state, action) => {
    //     return {
    //         collection: updateBook(state.collection, action.book),
    //         activeBookId: null
    //     };
    // }),
    on(BooksApiActions.bookUpdated, (state, action) => {
        return adapter.updateOne(
            {id: action.book.id, changes: action.book},
            {
                ...state,
                activeBookId: null
            })
    }),

    // on(BooksApiActions.bookDeleted, (state, action) => {
    //     return {
    //         ...state,
    //         collection: deleteBook(state.collection, action.bookId)
    //     };
    // })
    on(BooksApiActions.bookDeleted, (state, action) => {
        return adapter.removeOne(action.bookId, state)
    })
Enter fullscreen mode Exit fullscreen mode
  • Then create selectors using the entity adapter
// From:
// export const selectAll = (state: State) => state.collection;
// export const selectActiveBookId = (state: State) => state.activeBookId;
// export const selectActiveBook = createSelector(
//     selectAll,
//     selectActiveBookId,
//     (books, activeBookId) => books.find(book => book.id === activeBookId) || null
// );

// To:
export const {selectAll, selectEntities} = adapter.getSelectors();
export const selectActiveBookId = (state: State) => state.activeBookId;
Enter fullscreen mode Exit fullscreen mode

Adapter Collection Methods

The entity adapter also provides methods for operations against an entity. These methods can change one or many records at a time. Each method returns the newly modified state if changes were made and the same state if no changes were made.

  • addOne: Add one entity to the collection
  • addMany: Add multiple entities to the collection
  • addAll: Replace current collection with provided collection
  • setOne: Add or Replace one entity in the collection
  • removeOne: Remove one entity from the collection
  • removeMany: Remove multiple entities from the collection, by id or by predicate
  • removeAll: Clear entity collection
  • updateOne: Update one entity in the collection
  • updateMany: Update multiple entities in the collection
  • upsertOne: Add or Update one entity in the collection
  • upsertMany: Add or Update multiple entities in the collection
  • map: Update multiple entities in the collection by defining a map function, similar to Array.map

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay