Understand changes to model implementation
With NgRX Auto-Entity, a very small change must be made to how models are implemented. Standard @ngrx models are implemented as interfaces. A normal model used with @ngrx/entity may look like this:
This simple model would then be wired into @ngrx/entity using the adapter, with a selectId handler to allow entity framework to determine what the primary key of the entity is.
Due to the dynamic nature of how NgRX Auto-Entity works, interfaces are insufficient as they are compile-time only types in TypeScript. All of their information is ultimately stripped from the transpiled and optimized JavaScript code that you will ultimately release to a web server. To combat this issue, we must convert our entities to classes, which are a native runtime feature of JavaScript.
In addition to converting our model from an interface to a class, notice that we have also imported Key
from @briebug/ngrx-auto-entity
and decorated our id
property with @Key
. This is how the Auto-Entity framework is able to determine which property of the model represents the primary key. As with @ngrx/entity, this key is used to organize and look up entities stored in state.
Note that Auto-Entity supports composite keys. Simply decorate each property that participates in a primary key with the @Key
decorator if necessary.
A simple but common example of a composite key might be something along the lines of an order line item, which references both an order and a product along with a quantity:
For more detail about how composite keys work, read the advanced usage documentation on models and keys.
Understand changes to service implementation
With a normal @ngrx application, you are free to implement services however you see fit. There are no explicit requirements by @ngrx, since you are also on the hook to implement the effects as well, and it is your own effects that call your services.
NgRX Auto-Entities dynamic nature requires that data services implement the IAutoEntityService<TModel>
interface. This interface defines the contract by which Auto-Entity interacts with your services. This interface is described as follows:
This interface defines a different method that corresponds to each different kind of initiating generic action provided as a part of the NgRX Auto-Entity library. Every method provides entityInfo
as the first parameter, which contains metadata about the entity, including its name (based on the class name you defined for the model) as well as its type (the class you defined for the model). Each method also accepts a variety of other parameters, whatever may be necessary to support the unique behavior of that method.
Note that each method of the IAutoEntityService
interface is optional. Implement only what you need!
In addition to the basic CUD operations, we also support bulk versions of each CUD operation, as well as several options for loading entities. Each of the different load operations support different behavioral semantics, defined by the initiating actions and guiding how the meta reducer handles the data in state.
Each method of the IAutoEntityService
interface accepts, as the last parameter, custom criteria
. This allows you, the developer, to include any additional, arbitrary details that may be necessary to facilitate the desired operation, for any operation supported by this library.
Learn about the required paradigm changes for Auto-Entity
For NgRX Auto-Entity to function properly, some minor changes will be required in the way you implement a couple standard bits of code. This includes service implementations and model implementations. These changes are not particularly significant, and for services we provide a lot of meta information to assist you in achieving whatever is necessary for your applications.
As models and services are standard elements of any Angular application, there should be no additional boilerplate code to implement here. These would be implemented regardless. However, be aware of the nuanced changes in how the model and service are used, and the explicit interface requirement for the service.
More significant changes occur when utilizing facades to interact with state. Facades encapsulate the complexities of @ngrx, presenting you with a simplified, logical and more standard API into working with your stateful data.
Understand the changes to defining service providers
For most Angular applications, services can be provided very simply, simply by including the class in the array of providers
in your module. With NgRX Auto-Entity, due to its dynamic nature we must change how services for entities are provided a little bit.
Instead of registering the service itself directly, we must instead register the model class as the provider, and map it to an entity service via the useClass
option. Like so:
When dispatching an action, the model class is specified as the first parameter, and as such the model class is the only thing NgRX Auto-Entity can use to look up the necessary service provider. By mapping the model class to the service class, you are leveraging a standard Angular paradigm to support dynamic service lookup at runtime.