NgRx: Patterns and Techniques



  • Programming with NgRx is programming with messages. In NgRx they are called actions. To start an interaction a component or a service creates an action, populates it with data, and then dispatches it. The component does not mutate any state in place.
  • 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.
  • Workflow: The action is received and processed, which can be done in two ways.

    • First, an action can be processed by a reducer — a synchronous pure function creating applications states. It does it by applying an action to the current state of the application.
    • Second, an action can be processed by an effects class. An effects class taps into the Actions object (an observable of all the actions flowing through the app) to execute the needed side effects.
    • Finally, the component often reacts to the state changes by subscribing to the store. The following component gets an observable of todos. Any time a todo gets added, removed, or updated, that observable will emit a new array, which the component will display.
  • Actions
    • Actions can be divided into the following three categories: commands, documents, events.
      • 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 Eg. ADD_TODO

      • 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. Name documents using nouns or noun phrases

      • 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.
    • 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.
  • Processing Actions
    • A dispatched action can be processed by effects classes and reducers.
    • Reducers are simple: they are synchronous pure functions creating new application states.
  • Effects Classes
    • Effects classes have three roles:
      • They decide on how to process actions.
        • An action decider determines if an effects class should process a particular action. A decider can also map an action to a different action.
        • Decider can use either Action Type or Payload for making the decision
      • They transform actions into other actions.
        • A splitter maps one action to an array of actions, i.e., it splits an action. This is useful for exactly the same reasons as splitting a method into multiple methods: we can test, decorate, monitor every action independently.
        • An aggregator maps an array of actions to a single action. Aggregator are not as common as say splitters, so RxJs does not come with an operator implementing it. That’s why we had to add some boilerplate to do it ourselves. But could always introduce a custom RxJS operator to help with that.
      • They perform side effects.
    • Building Blocks

      These are the common building blocks used to implement application logic using NgRx:

      The best thing about them is how well they compose.

      Let’s look at a simple scenario first, where we select one type of action, execute needed side effects, and then update the state.

      Often that’s not enough, and we need to implement at a more complex scenario.

      In this scenario we start with a filtering decider, next we use a splitter. We then use a content-based decider for the top action. The bottom one is simpler. After executing the side effects, we aggregate the results and pass them to the reducer.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s