Using EntityAdapter with ComponentStore: @ngrx/entity Series – Part 3

As someone who enjoys the ComponentStore on an average level, I have written simple reactive CRUD logic several times. While storing a vast number of entities in the component state might not be a frequent use case, I will briefly illustrate the usage of the EntityAdapter with the @ngrx/component-store.

In this article:

yb
Yannick Baron is architecture consultant at Thinktecture and focuses on Angular and RxJS.

This is the third article of the series about @ngrx/entity.

  1. Managing Your Collections With EntityAdapter
  2. Multiple Entity Collections in the Same Feature State
  3. Using EntityAdapter With ComponentStore

Headsup

If you have followed the series, you should be familiar with the EntityState interface. It describes how the EntityAdapter expects our collection to be stored. In the previous articles, we elaborated in detail on how to handle single and multiple collections.
For this example, we simply make EntityState the state of our component and extend it with a couple of common properties. But everything shown before, when we need to handle multiple entity types, applies here as well!

Basic Setup

We start out by simply defining our component state interface, which will contain a single collection and some properties. We do this by extending EntityState:
				
					interface PersonComponentState extends EntityState<Person> {
  loading: boolean;
  error?: string;
}
				
			
Creating the EntityAdapter and the initial state can be done as before, and the ComponentStore goes along with it:
				
					const personAdapter = createEntityAdapter<Person>();

const initialState = personAdapter.getInitialState({ loading: true });

@Injectable()
class PersonComponentStore extends ComponentStore<PersonComponentState> {
  constructor() {
    super(initialState);
  }
}
				
			

Selector and Updater Bliss

Using the EntityAdapter, we can now easily manage our collection as we have seen before in our reducer functions, which will now simply become updaters:
				
					class PersonComponentStore extends ComponentStore<PersonComponentState> {
  // ...

  readonly addPerson = this.updater((state, person: Person) => {
    return personAdapter.addOne(person, state);
  });

  readonly updatePerson = this.updater((state, update: Update<Person>) => {
    return personAdapter.updateOne(update, state);
  });

  // ...
}
				
			
For selectors, we need to extract them from the EntityAdapter first:
				
					// ...

const { selectAll } = personAdapter.getSelectors();

class PersonComponentStore extends ComponentStore<PersonComponentState> {
  readonly persons$ = this.select(state => selectAll(state));

  // ...
}
				
			

Conclusion

In this series, I have shown, that using the @ngrx/entity package is quite simple and often beneficial. The way this abstraction is implemented allows us to make use of the EntityAdapter in various ways.
 
As this is the last part of this series, it is kept very brief. Please refer to the other parts for a detailed dive into how EntityAdapter works!
 
I hope I could inspire you to make use of the entity package!
Free
Newsletter

Current articles, screencasts and interviews by our experts

Don’t miss any content on Angular, .NET Core, Blazor, Azure, and Kubernetes and sign up for our free monthly dev newsletter.

EN Newsletter Anmeldung (#7)
Related Articles
AI
sg
One of the more pragmatic ways to get going on the current AI hype, and to get some value out of it, is by leveraging semantic search. This is, in itself, a relatively simple concept: You have a bunch of documents and want to find the correct one based on a given query. The semantic part now allows you to find the correct document based on the meaning of its contents, in contrast to simply finding words or parts of words in it like we usually do with lexical search. In our last projects, we gathered some experience with search bots, and with this article, I'd love to share our insights with you.
17.05.2024
Angular
SL-rund
If you previously wanted to integrate view transitions into your Angular application, this was only possible in a very cumbersome way that needed a lot of detailed knowledge about Angular internals. Now, Angular 17 introduced a feature to integrate the View Transition API with the router. In this two-part series, we will look at how to leverage the feature for route transitions and how we could use it for single-page animations.
15.04.2024
.NET
KP-round
.NET 8 brings Native AOT to ASP.NET Core, but many frameworks and libraries rely on unbound reflection internally and thus cannot support this scenario yet. This is true for ORMs, too: EF Core and Dapper will only bring full support for Native AOT in later releases. In this post, we will implement a database access layer with Sessions using the Humble Object pattern to get a similar developer experience. We will use Npgsql as a plain ADO.NET provider targeting PostgreSQL.
15.11.2023