Angular app with Ngrx for state management

Reading time: 7 minutes

Description

In this post I will demonstrate how to implement state management in a simple Angular app. NgRx store and NgRx effects will be used.

What is state management

First of all let’s talk about the state. State in simple terms is like a memory of a particular moment in time. Whenever some action happens the state changes. In a software engineering context you can think of a state as various related data that describes a particular moment. We normally store this data in a database. So whenever it is required to perform further actions to the actions that occurred previously to that moment we retrieve that state from the database. In addition to this we can store or keep some state in the application cache. There are various ways you can work with the state. It would depend on the type of application for example web or desktop.

What we will be focusing on this post is state management in the web application. In the present time web applications are becoming more advanced, this means more functionality, faster response time, busier pages etc.

To cope with this extra load of information we can use a state management framework like NgRx. This framework is based on the Redux pattern which is essentially a one way dataflow.

The concept of this pattern is that you replace the state object rather than modify it. This way the state stays immutable. Redux adheres to three principles.

What is required

  • Visual Studio code or any editor of your choice

Let’s create an Angular app

Open VS code and navigate to the root folder of the destination where you want to keep the code for this application.

In VS code new terminal type ‘cd destination-of-your-repo’ for example ‘cd C:\Users\dmitr\source\frontend\countries-ui’

Then type command ‘ng new name-of-your-repo’. In case you created the folder beforehand then you can run a command

ng new name-of-your-repo --directory=./ --skip-install

This would put application files into your folder without creating a nested folder structure.

Type ‘code .’ and it should open another VS code window with application code.

Next identify the folder where you package.json lives. You can run the command ‘dir’ to check if you are in the correct folder.

When you found it then run ‘npm install’

Let’s configure our app to use NgRx

First thing first we need to download it as a npm package. Use this command ‘npm i @ngrx/store’

This package would give us an ability to create a store where we will keep the state. This will be treated as a single source of truth across the application and the functionality that it will cover. The package would also contain code and types for reducer, action and selector. These are part of NgRx state management lifecycle.

Key concepts as described on NgRx website:

  • Actions describe unique events that are dispatched from components and services.
  • State changes are handled by pure functions called reducers that take the current state and the latest action to compute a new state.
  • Selectors are pure functions used to select, derive and compose pieces of state.
  • State is accessed with the Store, an observable of state and an observer of actions.

We would also need the ngrx effects npm package installed. Use this command ‘ npm i @ngrx/effects’

The effects package gives us an ability to correctly handle side effects in NgRx. Some actions in our application can have side effects. These are any effects that happen in the outside world that our application consumes or handles. These could be external devices, api that represent the external state.

When downloading these packages take into account the version of Angular installed on your machine. In other words make sure the version of NgRx you are downloading is compatible with the version of your Angular. To install particular version of npm package the format should be ‘npm install package-name@version-number’

Let’s configure app module to use NgRx

To initialize the store we need to add StoreModule.forRoot({}, {})
We are using forRoot since AppModule is our root application module.

When we use forRoot this means we are defining the main store of the application. Two arguments consist of reducers object and store config.

Then we register root level effects. EffectsModule forRoot takes an array of effects.

I also added ngrx store dev tools, additionally you would need to install a browser plugin. More details here.

There are various options that you can configure for dev tools. The one that you can see in the image is maxAge. This is the number of actions that are allowed to be stored in the history tree of dev tools. In a practice this is the number of state changes that you can replay. In other words you can check retrospectively and investigate what has been affected by one of the actions.

The app concept

The concept of the app will be to have two drop downs. First where you will be able to select a region. Either Asia or Europe. In the second dropdown user will be able to select the actual country. This will display some detailed information about the country.

There would be a component GeographicNavigatorComponent which will have a role of container/smart component. It will host two presenter/dumb components CountryListComponent and RegionListComponent. Also it will host a CountryDetailsComponent component that will only display the data like presenter/dumb component but at the same time will have an access to the store. This is just a basic configuration and you are more than welcome to modify it, so it answers to the best practices.

Additionally there will be a shared wrapper component for dropdown.

Let’s move on to adding some actual code

First of all we will add app state interface. It will represent the structure of our main state object.

It will comprise out of countries and regions object properties each representing their piece of the main state object.

Each piece of the state will have an initial state object. It provides a starting point when the application is first executed and potentially does not have any modified state. To make it predictable we will define the required values explicitly. To make it immutable we will declare it as constant. To have an initial state and declare it as a constant is a normal process. All of this assists in keeping the state in order and being able to quickly detect what happened in case there is an error.

The way we will structure our app in terms of state is we will create a state folder for each section of the state. This is in addition to countries and regions having their own modules.

We will also need to add some models. These would be used to construct our binding model. Also these would be reused in stores and all sorts of data manipulation.

To get our data we will be using an online countries api available at https://restcountries.com which is provided under Mozilla Public License. This means it’s free and open-source software.

And for that we need a service. Where we will make calls. Format and map data as we need it.

Let’s have a look on main components structure of the app

As I mentioned previously there will be a host or parent component called GeographicNavigatorComponent.

It will be a main point of communication with the store. So that whenever the data is updated or refreshed for any of the reasons it will communicate to all other components that are part of this component or chain of components. Respectively if any action that is triggered in the presenter/child component then it should be outputted to the parent, so it can trigger the required action to complete the presenter action.

This is the flow of the container-presentation pattern. This can be handy to divide growing stateful logic into more organized form, so it’s easier to track where problems occur.

To note the important bits of using ngrx. Whenever we want to get a particular piece of state we use selectors. Whenever we need to do something we dispatch an action. Actions can be triggered by the user . They also can be triggered by the external systems actions like api requests and other devices. These actions are then processed in reducers which perform transition from one state to another.

What you need to make sure is so that your component is subscribed to the correct selector. Because whenever some other component dispatches an action and it finishes processing in the reducer that state transition would be reflected in the store. Hence the component with the selector would automatically select this.

Let’s have a look on how things work with ngrx

What we will do is we will review the scenario where all the pieces of ngrx pattern are used.

We will start from countries effects. Effects are they way of communication of our system with external sources.

In our case this effect method would be called by GeographicNavigatorComponent to get a list of countries. When a call to http api is successful we will call a success action. A common approach for a single operation is to have three actions. One is the load action, then success and failure action.

As you can see we call the getCountryListSuccess action with countries as an argument or props method as it’s called according to ngrx docs.

For each action we have an associate state change function in the reducer. In that function we either assign a part of the state or perform some changes to that piece of state. To use the correct words we process the transition of the state rather than change. Since you shouldn’t mutate the state, it should be immutable. The way we can achieve this is by replacing the whole state object. You can see it when we return an object with the state object that we apply spread operator to. And reassign any state object property to the required state. I promise it’s easier that it sounds when you start working with it.

Another point I want to mention to you. The way we configured this application modules ngrx is we have a main app.module that uses StoreModule and EffectsModule forRoot. It’s pretty self explanatory and you might have already seen something similar that Angular uses for routing. It’s the method that is invoked initially when the application loads. It provides the initial configuration with reducers, actions, selectors.

Then there is also forFeature option. This can be used with lazy loading of modules functionality. Also gives you an ability to define its own piece of state. So you can focus on a particular feature of the app and organize your code. This doesn’t create any new store context. It uses the same as the one that was created with forRoot. It loads that piece of state whenever it is required by the application area. As in our example we have a countries feature state. It’s loaded once we activate this part of the application by means of using this component in the GeographicNavigatorComponent template. The example that could give better understanding and will have more justification to use forFeature option is for the case when app redirects from list component to details or form component. The form component doesn’t need to load it’s state without redirection to it by the user’s actions.

Conclusion

The main concept of Ngrx is to have a single source of truth in the format of an object. It is called the store. Basically the store can contain different feature stores or parts that construct the main store object.

The only way to change the store is through dispatching an action. Which is then processed or reduced in the reducer. By having this predefined unidirectional flow it is easier to predict what would happen or what caused a particular transition in the state. Although the correct way of saying it is that action produced these new results. Since when the data was processed in the reducer it effectively created a new state. This way the immutability of the state is supported.

This tutorial demonstrated the beginners level application with standard ngrx functionality. Overall this should be a good start for someone new or it could be a reference point for future developments.

You can find a complete code here.

Publish npm package as Node js module

Reading time: 7 minutes

Description

In this post I will demonstrate how to set up everything you need in order to be able to publish the npm package and use it as a js module in another application.

What is required

  • Npm account
  • Visual studio code

First thing first make sure you have a local environment and workspace for Angular app setup. If you got it then skip the next step.

1 step: Setup local environment and workspace for Angular app

Install Visual Studio Code on your machine. Please use the link below.

https://code.visualstudio.com/download

Then you need to install an appropriate Node.js version that is compatible with your version of Angular.

https://nodejs.org/en/download/

2 step: Create npm account if you haven’t got one

Go here https://www.npmjs.com/signup

TO NOTE: Make sure you confirm your account from your email box.
Or you might have errors when trying to login to npm through VS code.

3 step: Login to your npm account through VS code

Assuming you got VS terminal open

  • type in > npm login
  • follow on screen instructions
  • to accept your input press Enter key
  • when you are typing password it wont show it but it’s there….magic

*npm config file for user – .nprmc, can be found at this location C:\Users\YourName
make sure the registry is set to npm like so registry=https://registry.npmjs.org/

4 step: Create npm package

  • navigate into the root folder using > cd folderDestintation e.g. cd C:\Users\dmitr\source\frontend
  • create new directory by typing > mkdir name-of-your-package
  • navigate into newly created directory using > cd name-of-your-package

  • initiate the package with package.json by typing > npm init
  • use this command to go to code > code .

5 step: Create Angular app

It is a straightforward task once your local environment and workspace is set up.

*workspace here I mean the area on your computer rather than angular workspace

  • Open new window in VS code
  • Go to menu option Terminal > New Terminal
  • Optional: Install the latest Angular version globally with this command > npm install -g @angular/cli
  • navigate into the root folder using > cd folderDestintation e.g. cd C:\Users\dmitr\source\frontend
  • type in > ng new your-app-name
  • go to the root folder where app was created by typing > cd your-app-name
  • then by typing > code .
  • new window should open with the app

*ng-new creates a new app that is default project for new ng workspace
*ng serve -o – opens the application in the browser. Prefix -o opens the application in the browser.

Ok we finished setting things up.

Next we need to add some code to our package.

In the package application add new file index.js, it’s going to be our entry point as we previously configured in package.json.

exports.printMsg = function () {
    console.log("This is a message from the demo package");
}

The whole project should look like this.

We are ready to publish.

Since we logged-in in one of the previous steps we will go straight to publishing.

Unless you have a paid account type with npm we can only publish public packages. In other words a package that can be seen and used by everyone.

We will publish an unscoped public package.

Let’s go to npm and check whether our package is there.

Ok let’s get back to the Angular app and let’s use our newly published npm package.

We need to modify the main app component’s ts file. Then we install our npm package using > npm i your-package-name

You can find a complete command on your npm account on your package details page.

In order to consume our package module with Angular we need to use Node.js require function. We also need type definitions for the node. These should be installed once you run the ‘npm install’ command in the terminal. To be sure you can run > npm i @types/node

For these definitions to be found we need to reference them in tsconfig.app.json file. To note it’s tsconfig.app.json and not tsconfig.json.

Check how to do it for your Angular version. Mine is 11. To check angular version either run ‘ng –version’ or ‘npm list -global –depth 0’

Let’s run the Angular app and see if it uses our npm package.

In the terminal run ‘ng serve -o’ command. This should open the app in the browser. Let’s hit F12/open developer tools and check in the console for our package message.

Next thing is let’s update our npm package and re-publish it.

For this we need to change the version by using the ‘npm version 2.0.0’ command. Npm follows semantic versioning, more details here.

Let’s change the console.log message as well.

Then we need to use the command ‘npm publish’ again. You can check on your npm account if the package version was changed.

Next let’s update our package in the Angular app.

We can check if there are any outdated packages by using the ‘npm outdated‘ command in the terminal of our Angular app.

There are multiple but for now we keep the focus on our npm package.

To update we will use ‘npm i your-package-name@latest’ or ‘npm i your-package-name@1.0.0’ with a particular version.

Alternatively if you want to update all the outdated packages then use the ‘npm update’ command. If nothing gets updated then try ‘npm update -dd’ which will give you more details. Possibly you would need to adjust the maximum version in the package.json file.

Let’s run the Angular app again and see if it uses the latest version of our npm package.

Same as previously ‘ng serve -o’, F12/developer tools and check the Console for the message.

Conclusion

As you can see, creating the npm package is straightforward. Npm documentation is clear and concise.

It is very handy to have regularly used pieces of code placed into the package. You can reuse it anywhere you want. You can share it. Plus it is easy to locate it in case you need to modify it. Finally you are avoiding code duplication. Hence less code. It is especially valuable for front end apps.

Source code can be found here for npm package and here for Angular app.

Continuous Deployment of Net Core Web App to Azure App Service

Reading time: 15 minutes

Description

In this post I will explain how to setup continuous deployment of Net Core Web App with Azure DevOps for the app that is hosted with Azure App Service.

What is required

  • Azure Subscription
  • Net Core Web App
  • Repository/Repo on Azure DevOps

Let’s start with initiating a repository on Azure DevOps

Prerequisite: you need a project on Azure DevOps. Go to your Azure DevOps main page.

Once you have clicked Create you should see similar screen.

We are interested in Repos section.

Look at the top section of the page where it says Initialize with README or gitignore. In my opinion it is a good practice to have both of these files with every repository you are creating.

With README you are deemed at some point to add some description of your app. This serves as an initial documentation. Whereas gitignore will prevent you from commiting unnecessary files to your repository. In a production environment this save your builds and time in case one or few files has slipped through.

At the end of the day you can always delete them or edit them according to your requirements.

Clone repository

Next thing is to Clone this newly created repository to your machine.

You can use any GUI for Git to do it or even Git Bash if you prefer command line type of application.

For this case I will use Sourcetree . It’s relatively easy to use. Gitextensions is similar in touch and feel. It also nicely connects with various comparison/diff and merge tools.

The main thing for us is to memorize the destination where we clone our reposity.

Create Net Core App

Let’s create Net Core web app with Visual Studio.

Since we already created a solution folder when we cloned the repository to our machine make sure in Location field we target the folder that contains the solution folder named NetCoreWebApp. Visual studio clever enough to place web app files into this folder.

Then we select ASP .Net Core 3.1 with Angular template.

The final folder structure should looke like so.

NetCoreWebApp inside has this structure.

Alternatively you can always create web application at one destination and then simply copy or move it over to the repository location.

In either way the result that we aiming for is for Git to track the changes to the repository.

As you can see Sourcetree on top of Git picked up the changes to your repository.

Steps that you need to do next are:

  • Good practice is to Build the solution but in this case it can be optional since it’s a pre-made template
  • Stage All
  • Write commit message
  • Commit
  • Push it to the remote server.

Once all of these steps are performed you would be able to see your changes on your repository at Azure DevOps.

Build pipeline

Select Pipelines from left menu and Use the classic editor.

Then select the repository you wish to setup the build pipeline.

Then you need to choose ASP.NET Core template.

The next screen should look like this.

The only thing that needs changing is on the Triggers tab.

This way we enable Continuous integration. Which means every time you commit changes to this branch it would trigger the build pipeline. As a result you would be able to see whether your changes integrate into the code of remote copy of the branch. In our case it’s master. Normally you would have build pipeline on develop branch before merging and building it on master branch.

Next step is to click on Save & queue. Then we need to add comment, check the branch and click Save and Run.

Next screen should look like this.

Next we need to create an App Service

For this we need to go to Azure Portal.

There we need to select Create Resource.

Then select Web and Web App.

Things to fill in on the next screen:

  • Resource Group -> Create new, choose whatever name you like since by it you will distonguish resource group that is related to particular project.
  • Name – which would be part of web app url
  • Way of publish – Code
  • Runtime stack that your app would use to run
  • Operating system – Windows
  • Region – whatever you like. Mind since we are using free subscription you need to make sure it is available in that region.
  • Windows Plan -> Create new
  • Free F1 tier which is part of free subscription from Azure for individual developers that want to research this platform

If you go to your newly created resource and there select App Service. From there you can check the app if it’s ok and running fine by clicking on it’s url.


Let’s go back to Azure DevOps and create Release pipeline.

…before getting into final part I think it’s a good time for a cup of beverage of your choice 😉

Create Release pipeline

Click on Releases from left pane menu. Then click on New pipeline in the area on the right.

Search for Azure app in the search box for templates. Click Apply.

From there you can edit stage details like name and owner. This could be develop stage with one of the testers being the owner. However in our case we will leave these as they are.

We are more interested in editing job/task section. So let’s click on section that is underneath Stage 1 in Stages on the left side.

In here we need to select our Subscription and App service name that we created at Azure portal.

Once we selected and Authorized our subscription we can then see our available App services.

Let’s go back to tab Pipeline and add an Artifact that was created by the build pipeline. Click on Add an artifact.

Select appropriate build pipeline Source. Check alias and edit it if needed. Click Add.

Last bit of setup. The Continuous deployment trigger.

Save and click Create release.

Select the Stage and build version that you want to release.

Once you are happy click Create.

Go to Releases on the left pane. In the right section click on Releases.

You would need to deploy the first release manually. On the next screen click Deploy and off it goes!

You can monitor the process in the next screen.

To check your newly released web app select Deploy Azure App Service.

For this purpose use App Service Application url.

Let’s check out the result! Our Hello, world app! Classic 🙂

Conclusion

Hope you enjoyed this post.

As you have noticed with Azure it is quite straight forward to deploy an app. From creating an App service in portal to creating build pipeline with Azure DevOps. When you have done it once or twice it makes sense. You can easily connect the dots to get the whole picture of modern deployment processes.

Stay tuned and have fun coding.