Jim Lynch Codes
  • Blog
  • About Jim

Writings about one coder's stories & experiences.

Understanding The "[__] __" Syntax For Ngrx Action Types

2/6/2017

0 Comments

 
If you've taken a look at some open source projects that use Ngrx such as example-app, ngrx-examples , or angular-nye-advanced-ngrx then you may have noticed that they have an interesting way of defining Action types. In this post I'll go over why we use the "type" method and why we construct the Action strings in this specific style. Big thanks to Xavier, @xlozingues, for staying at the office late on a Friday to help me understand this. ? ​

Other Ngrx Posts

This is an intermediate-advanced post about a specific aspect of Ngrx. If you're new to using Ngrx I recommend checking out my earlier post Setting Up An Angular 2 Project With Ngrx. 

The Simple Way

I'm almost embarrassed to admit that when I first got started with ngrx I didn't fully understand the weird brackets-in-a-string syntax. I didn't think it  was a big deal so my original Ngrx example project's Action types were straight up strings! My code would look something like this:
export const ActionTypes = {
  SEARCH:                               'SEARCH',
  GET_VIDEOS:                           'GET_VIDEOS',
  ANONYMOUS_AUTH_SUCCESS:               'ANONYMOUS_AUTH_SUCCESS',
  BEGIN_ANONYMOUS_AUTH:                 'BEGIN_ANONYMOUS_AUTH',
  NO_ACTION:                            'NO_ACTION',
  CREATE_NONANONYMOUS_USER_OBJ_IN_DB:   'CREATE_NONANONYMOUS_USER_OBJ_IN_DB',
  USER_OBJ_CREATION_COMPLETE:           'USER_OBJ_CREATION_COMPLETE',
  CREATE_ROOM:                          'CREATE_ROOM'
};

The "type" Method

I'm not sure who started this tradition it, but the official ngrx example's actions use this somewhat strange "type" method when defining their actions (see the original source for the type method here). Now, the action It looks something like this:

export const ActionTypes = {
  SEARCH:           type('[Book] Search'),
  SEARCH_COMPLETE:  type('[Book] Search Complete'),
  LOAD:             type('[Book] Load'),
  SELECT:           type('[Book] Select'),
If you've never seen this before then it should look pretty weird. At first I thought they were defining an array since the square brackets in JavaScript / TypeScript normally represent an array. However, here's is the key thing to realize about this "[__] __" syntax: the square brackets are completely irrelevant and optional! Really, you could use any string and wrap it in the type() method. So, what's the point of wrapping your strings in this method called type? All the method is really doing is checking if you have already defined an action as that  same string and throws an error if they match exactly.

The Square Brackets

In the very first code snippet of this post that illustrates the "pure strings" method we are define variables for the strings that will define the type of a particular action. This is nice because the IDE will let us know if we spell something incorrectly. We get this from the act of creating variables for our action strings (as opposed to hardcoding our strings right in our code when we want to use them). However, we can do even better! In many Ngrx examples they use this square bracket notation to define their strings. Often there are actions that complement each other; a ying and yang relationship between actions for some specific event that occurs in your application. Especially when dealing with side effects, there is normally a "beginning action", a "success action", and often the third-wheel "failure action". With this recommended syntax we place these begin, success, and fail modifiers outside of the square brackets, and inside the square brackets we write some name that describes the overall event that is happening in this group of actions. The word or words inside the brackets describe really describe what action you're dealing with, and the word (or words) outside the brackets sort of describe the point in time of the "action lifecycle" (yes, I just made up that phrase, but hopefully you know what I mean). For example, we might write the anonymous authentication action types like this:
ANONYMOUS_AUTH_BEGIN:    type('[ANONYMOUS AUTH] BEGIN',
ANONYMOUS_AUTH_SUCCESS:  type('[ANONYMOUS AUTH] SUCCESS',
ANONYMOUS_AUTH_FAIL:     type('[ANONYMOUS AUTH] FAIL'
Wow, Look at how clean and understandable that is! We can easily see that these three actions are all related to each other in that they are actions that have to do with anonymous authentication. We can also clearly see which is the begin, success, and failure action! I also think the spaces instead of underscores add an extra little sliver of readability as well. 

Why The "type" Method Is Awesome

The "type" method is extremely helpful for making actions because it prevents a set of bugs that could arise from accidentally using the same string for two different actions. Once your team of developers and/or application starts growing to multiple stores, reducers, and action creators you may at some point accidentally use the same string for two actions that are meant to be completely independent. Suppose you did this and didn't use the type method; what would happen? The short answer is bad things will happen! When you fire one of these actions your reducers / effects will basically think both actions are being dispatched and thus will try to manipulate the state, trigger side effects, etc. for BOTH of these actions each time you dispatch either of them! You (or worse, your users) may notice subtle bugs and weird things happening with the state although no errors are being thrown. From a developer point of view this a very difficult problem to notice and debug, and it kept people up at night so much so that it inspired this type method to be created and declared as a best practice when defining Ngrx actions. With the type method, if you duplicate a string you will be immediately notified when you run your app as it will prevent the page from loading and throw an error about Action types not being unique:
Picture
Now that's one error you should be glad to see! So now that you are aware of this type method and why it's so wonderful for defining Ngrx Action type strings, make sure you use it!
0 Comments

Your comment will be posted after it is approved.


Leave a Reply.

    ​Author

    Picture
    The posts on this site are written and maintained by Jim Lynch. About Jim...
    Follow @JimLynchCodes
    Follow @JimLynchCodes

    Categories

    All
    Actionscript 3
    Angular
    AngularJS
    Automated Testing
    AWS Lambda
    Behavior Driven Development
    Blockchain
    Blogging
    Business Building
    C#
    C / C++
    ClojureScript / Clojure
    Coding
    Community Service
    CS Philosophy
    Css / Scss
    Dev Ops
    Firebase
    Fitness
    Flash
    Front End
    Functional Programming
    Git
    Go Lang
    Haskell
    Illustrations
    Investing
    Java
    Javascript
    Lean
    Life
    Linux
    Logic Pro
    Music
    Node.js
    Planning
    Productivity
    Professionalism
    Python
    React
    Redux / Ngrx
    Refactoring
    Reusable Components
    Rust
    Security
    Serverless
    Shell Scripting
    Swift
    Test Driven Development
    Things
    TypeScript
    Useful Sites
    Useful Tools
    Video
    Website Development
    WebStorm
    Writing

    Archives

    August 2021
    February 2021
    January 2021
    October 2020
    September 2020
    May 2020
    April 2020
    February 2020
    January 2020
    December 2019
    October 2019
    September 2019
    August 2019
    July 2019
    June 2019
    May 2019
    April 2019
    March 2019
    February 2019
    January 2019
    December 2018
    November 2018
    October 2018
    September 2018
    August 2018
    June 2018
    May 2018
    April 2018
    March 2018
    February 2018
    January 2018
    December 2017
    November 2017
    October 2017
    September 2017
    August 2017
    July 2017
    May 2017
    April 2017
    March 2017
    February 2017
    January 2017
    December 2016
    November 2016
    October 2016
    September 2016
    August 2016
    July 2016
    June 2016
    May 2016
    April 2016
    March 2016
    February 2016
    January 2016
    December 2015
    November 2015
    October 2015

    RSS Feed

  • Blog
  • About Jim
JimLynchCodes © 2021