How to Ensure NgRX Actions are Unique
I don’t know about you, but one of the main problems I’ve always had with NgRX is that the Action Type relies on strings. And, every time I create a new set of Actions, I typically copy and paste from an existing actions file and modify the strings. Of course, some times I forget and then I end up with code in two different places firing at strange times and getting results showing up that I didn’t expect.
Getting On The Same Page
First, let’s review what an NgRX Actions file should look like:
You may have seen a form of this file that uses constants for the strings instead of the enum type.
In some ways, using const is easier. But, by using enum we get the added advantage of not having to cast our actions in our Reducer because the TypeScript Discriminated Union feature kicks in.
A Discriminated Union allows us to use a switch or an IF statement against an enum and because we’ve done so, it automatically knows that they type we are dealing with matches that type. See the section on Discriminated Unions on this page https://www.typescriptlang.org/docs/handbook/advanced-types.html.
What this means is that our reducers can be coded like this:
You should notice that we specified that the
editReducer function specifies Edit.Actions a the parameter type that is passed in and yet on line 16, the code knows that action.form exist because it is of type UPDATE.
If you aren’t familiar with this form, you’ll notice that we didn’t provide a type for the type property in our classes. If we do, we no longer get the benefit of our reducer being able to deduce which type of Action our action is. This one place where string typing might get in the way.
And now that we are all on the same page regarding how to create and use Actions in NgRX, the next step is to ensure our Actions are unique.
For this we will need to create a new function called
isUniqueString(val: string); The purpose of this function is to ensure that each string it is passed is unique from every previous string it was passed.
For those of you who might be concerned that uniqueStringMap is a global variable that isn’t encapsulated. Because of the way that the modern bundelers work, uniqueStringMap only exist and is only available to the file it is declared in because we never exported it.
To use this, we add a small bit of code at the end of each of our actions files.
Here we are making use of
Object.values() to turn our Type
enum into an array of the enum’s values. Then we are using
forEach() to loop through those keys and check them with
Now, what may not be obvious about this code is that it will run as soon as it is loaded. If there is a collision with another action, an exceptions will get thrown and your code will stop working. This makes it painfully obvious that you have a problem and because we tell you exactly what key is in conflict you know exactly where to look.