Upgrade to Pro — share decks privately, control downloads, hide ads and more …

@ngrx/entity - Managing collections with ease

Yannick Baron
February 24, 2023

@ngrx/entity - Managing collections with ease

Using @ngrx/store or @ngrx/component-store?
Handling lists of entities yourself?
@ngrx/entity and EntityAdapter to the rescue!

Yannick Baron

February 24, 2023
Tweet

More Decks by Yannick Baron

Other Decks in Technology

Transcript

  1. @ngrx/entity
    Yannick Baron
    @yannick_baron
    Software Architecture Consultant
    Managing collections with ease

    View full-size slide

  2. • hold several entities


    • entities unique/identi
    fi
    able


    • can have an order


    • can be implemented by various data structures
    Collections

    View full-size slide

  3. • add an entity, add many, ...


    • update an entity, update many, ...


    • remove entity, remove many, ...


    • read speci
    fi
    c entity,
    fi
    nd entities matching a condition, ...
    Operations on Collections

    View full-size slide

  4. Immutable updates on arrays

    View full-size slide

  5. // collection

    let collection: Entity[] = [...];
    // item we want to add

    const newItem: Entity = { id: 'itemId', ... };
    // simply appending to the end

    collection = collection.concat(newItem);

    collection = [...collection, newItem];


    // beware of duplicates + order
    Adding to the collection (array)

    View full-size slide

  6. // collection

    let collection: Entity[] = [...];
    // id we want to remove

    const removeId = 'itemId';
    // filter the collection

    collection = collection.filter(item => item.id !== removeId);
    Removing from the collection (array)

    View full-size slide

  7. // collection

    let collection: Entity[] = [...];
    // item we want to update

    const updateId = 'itemId';

    const update: Partial = { foobar: 42 };
    // map the collection

    collection = collection

    .map(item => item.id === updateId ? { ...item, ...update } : item);
    Updating an item in the collection (array)

    View full-size slide

  8. // collection

    let collection: Entity[] = [...];
    // id we are trying to find

    const target = 'itemId';
    // find in the collection

    const item: Entity | undefined = collection.find(item => item.id === target);
    // worst case: iterates whole list without a match
    Read an item from the collection (array) by id

    View full-size slide

  9. // collection

    let collection: Entity[] = [...];
    // filter the collection

    const items = collection.filter(item => item.foobar >= 42);
    Find items in the collection (array) by condition

    View full-size slide

  10. • many applications handle one or many collections of entities


    • always same/similar CRUD code


    • often similar logic in regards sorting + uniqueness of items


    → Abstraction possible!


    → @ngrx/entity provides the EntityAdapter
    Boilerplate? Repetition?

    View full-size slide

  11. Introducing the EntityAdapter

    View full-size slide

  12. • stateless class provided by the @ngrx/entity package


    • stores many entities ef
    fi
    ciently


    • provides methods and selectors to manage a collection immutably


    • agnostic, can be used in many contexts (Store, ComponentStore)


    → reduces boilerplate / repetition


    → keeps reducers small
    What is the EntityAdapter?

    View full-size slide

  13. const entityAdapter = createEntityAdapter();


    // optionally provide id accessor and/or comparator

    const personAdapter = createEntityAdapter({

    selectId: ({ uid }) => uid,

    sortComparer: (p1, p2) => p1.foobar - p2.foobar,

    });
    Creating an EntityAdapter

    View full-size slide

  14. let collection = entityAdapter.getInitialState();


    // optionally initialise additional state properties

    let collection = createEntityAdapter({

    loading: false,

    });
    Get the initial collection state

    View full-size slide

  15. // add one

    const newItem: Entity = { id: 'item-1', ... };

    collection = entityAdapter.addOne(newEntity, collection);


    // remove one

    collection = entityAdapter.removeOne('item-2', collection);


    // update one

    const update: Update = {

    id: "item-2",

    changes: { foobar: 52 },

    }

    collection = entityAdapter.updateOne(update, collection);
    Update the collection

    View full-size slide

  16. const { selectAll, selectTotal } = entityAdapter.getSelectors();


    const all = selectAll(collection);

    const count = selectTotal(collection);
    const { selectEntities, selectIds } = entityAdapter.getSelectors();


    const entity = selectEntities(collection)["item-1"];

    const ids = selectIds(collection);
    Read from the collection via selectors

    View full-size slide

  17. • easy to use


    • reduces boilerplate / repetition


    • use with Store and ComponentStore


    → use it


    → make your life easier
    EntityAdapter

    View full-size slide

  18. It's a wrap!
    @yannick_baron


    [email protected]

    View full-size slide