My favorite talk at ng-conf this year was by Mike Ryan; it was called “Good Action Hygiene with NgRx.” I really liked this talk because Ryan didn’t just explain how to do something – he actually took a stand, giving his opinion and values about what we should be doing in the first place. This talk impressed me and changed the way I think about writing code – and shouldn’t that be the goal of every talk?

In addition to its technical content, Ryan’s talk is centered around the virtue of empathy – empathy for your fellow developers and for your future self. “Good Action Hygiene” means thinking of these others as you write your code here and now, and crafting your code so that it will be intelligible to them, and as easy to understand as possible.

If you’re like me, you’ve probably thought of @ngrx actions as fairly uninteresting. After all, they do not contain any complex state or logic, but are instead just a glorified string indicating an action type, plus maybe some other arguments for extra flavor. Ryan turns this on his head: He calls actions the “bedrock” of an application.

What makes actions so important? For one thing, your total set of actions can describe your application as a whole, by listing out all the events that can happen to it – whether they be initiated by a user, an API server, or the browser. Conceived this way, the actions in some sense are the application, or at least its essential elements. By tackling actions as a coherent group, you can get an unrivalled view of your application overall, and just as important, this overall view can be easily shared amongst your team members and your future self.

From this perspective, Ryan details a set of pitfalls that tend to arise when using @ngrx. They all stem from failing to grasp the basic idea that actions are meant to communicate and explain the basis of the entire application. And they are quite surprising!

The first pitfall is re-using actions, that is, sending the same action from different points in your code. Right away Ryan attacks a practice many programmers consider sacred: the DRY principle, or code re-use. What Ryan is arguing is that even if you have already created an action which would trigger the effect you want, if it is sent from a different place then you should create a different action. “Wait, what?” I hear you asking. “I should repeat myself? I should not re-use my existing code?” That’s right: specifically: It’s ok to dispatch two different actions that trigger the same effect. In fact, Ryan argues, it should be encouraged. The difference between such actions should be marked because the actions are triggered from different places – this means they are different events.

What are the benefits of this to your colleagues and your future self? Well, imagine reading through a log of your actions. Which sequence would you rather read?

Sequence A:

Add Item to Cart

Add Item to Cart

Sequence B:

[ Search Results ] Add Item to Cart

[ Item Detail Page ] Add Item to Cart

By creating different actions that specify in detail the source of your events, you have increased the readability of your program, and helped your colleagues and your future self. Multiply that readability by the dozens or hundreds of actions in your application and the benefit here is significant.

(Don’t worry that this will make your code hard to maintain – Ryan shows that it won’t in his talk.)

A second, related pitfall is the use of “generic action types.” Ryan is not talking about the typescript type system here. Instead, what he means is that your actions should be given descriptive names that indicate from where they are triggered. Compare the experience of reading this in the log:

Sequence A:

[User] Authenticate

[Cart] Cancel

[Cart] Checkout Success

Sequence B:

[Login Page] Login

[Cart: Finalize Order] Cancel

[Cart API] Checkout Success

Again we see a nice increase of readability, especially for new team members and your future self a year down the road.

Ryan also makes an argument about designing an application, and how actions can fit into that process. He says we should write our actions first:

The best way that I have found to avoid these pitfalls is to write actions first when you go to build a new feature… If you’re on a team you need the actions to be written before you can write the reducers or the effects or the containers. So by writing those actions first, you’re unblocking other developers on your team from building the rest of that feature in parallel.

In addition to these organizational benefits, writing actions first helps us avoid the pitfalls Ryan has detailed. Listing out all of the actions involved in a feature or new app encourages us to give unique and descriptive names to each of them, and protects us from the temptation of reusing actions in different areas. Finally, writing actions first can help provide developers with a shared sense of the feature or app as a whole as well as a language to talk about it.

In sum, I thought Ryan’s talk was excellent. It changed the way I think about Angular development. I hope it has given you some food for thought.

Comments on reddit.