Action

In NgRx, an action has two properties: type and payload. The type property is a string indicating what kind of action it is. The payload property is the extra information needed to process the action.

As in most messaging systems, NgRx actions are reified, i.e., they are represented as concrete objects and they can be stored and passed around.

NgRx is a very simple library, so it does not make a lot of assumptions about your actions. NgRx does not prescribe one way to construct them, nor it tells us how to define types and payloads. But this does not mean that all actions are alike.

Three Categories of Actions

Actions can be divided into the following three categories: commands, documents, events.

Interestingly, the same categorization works well for most messaging systems.

Commands

Dispatching a command is akin to invoking a method: we want to do something specific. This means we can only have one place, one handler, for every command. This also means that we may expect a reply: either a value or an error.

To indicate that an action is a command I name them starting with a verb.

Documents

When dispatching a document, we notify the application that some entity has been updated — we do not have a particular single handler in mind. This means that we do not get any result and there might be more than one handler. Dispatching a document is less procedural.

Finally, I name my documents using nouns or noun phrases

Events

When dispatching an event, we notify the application about an occured change. As with documents, we do not get a reply and there might be more than one handler.

Naming Conventions

I found using the naming convention to indicate the action category extremely useful, but we can go further than that and impose a certain schema on an action category. For instance, we can say that a document must have an ID, and an event must have a timestamp.

Using Several Actions to Implement a Single Interaction

We often use several actions to implement an interaction. Here, for instance, we use a command and an event to implement the todo addition. We handle the ADD_TODO command in an effects class, and then the TODO_ADDED event in the reducer.

Request — Reply

As I mentioned, when dispatching a command, we often expect a reply. But the dispatch method does not return anything, so how do we get it?

Let’s look at the following component managing a todo. In its delete method we want to confirm that the user has not clicked on the delete button by accident.

This operation will probably display some confirmation dialog, which may result in a router navigation and a URL change. These effects are not local to this component, and, as a result, must be handled by effects classes. This means that we have to dispatch an action.

Now imagine some effects class handling the confirmation. It will show the dialog to the user, get the result and store it as part of the application state. What the todo component needs to do is to query the state to get the result.

Now how we are using the todo id to get the right reply. Ids used in this fashion are called correlation ids because we use them to correlate requests and replies. Entity ids tend to work well for this. But when they don’t, we can always generate a synthetic correlation id.