Ethereum and Angular — Part 3

NGRX

GrandSchtroumpf
B2Expand
4 min readMay 2, 2018

--

In part 1 and part 2 we setup a Dapp based on Ethereum andAngular. In this part we’ll implement NGRX.

You can find the code here :
https://github.com/B2-Expand/angular-ethereum-boilerplate

First let’s install the main module of NGRX: @ngrx/store. It allows us to keep the state of the application in one place :

We also need @ngrx/effectsto link our service with the store:

With NGRX you can use the Redux development tools which can save hours of debugging (I know something about it…). To use it you need to install ngrx/store-devtools:

Once these modules are installed, they must be imported into our Ethereum module ethereum.module.ts :

  • StoreModule contains the Redux state of the module (which we will code later).
  • EffectsModule contains the list of Effects classes used in our module. This can be seen as the `providers` for NGRX Effects.
  • StoreDevtoolsModule allows us to use Redux development tools available on Chrome and Firefox.

To get Redux development tools on your browser. Go to extensions (chrome) / add-ons (Firefox) and search for “Redux Devtools”.

Architecture

NGRX requires a very specific architecture that we will implement in the ethereum folder :

Ethereum :

  • eth.service.ts : our service, allows us to interact with Ethereum
  • eth.actions.ts : actions that send information to the store.
  • eth.reducers.ts: the reducer that specifies how the application state should respond to an action sent to the store.
  • eth.effects.ts: the side effects that allow us to use our service methods in response to actions.
  • eth.selectors.ts: functions that will be used in our component to listen to a particular application status change (for example: the selected account)

Service

We already have our eth.service.ts:

This service allows us to retrieve the list of available accounts and the selected account. Our goal is to keep in the state of the application the list of these accounts and the one selected.

Actions

Let’s start by writing the actions. They alert the store that the state should change in response to an action (from the user or from Ethereum):

Types

There are a lot of things here. First of all, let’s define the kind of actions our application can do. These are string that will be evaluated by the reducer and effects later. Here we have four::

Get Accounts

This is used by the effects to trigger our service to retrieve the Ethereum accounts on our user’s node. This action is used by the effect because it needs to get data outside of the state (here the user’s node).

Get Accounts Success

The purpose of this type is to inform the reducer that the application has received the list of accounts. Then it’ll be store in the state.

Sélectionner un compte à utiliser

This type will be listened by the reducer to tell the store which account is selected, an by an effect to change the web3.eth.defaultAccountof the node.

Error

This type makes it possible to manage the errors which would come from the communication with Ethereum.

Actions

Actions are used to send information to the store. They parameters :

  • type: a string that describes the type of the action performed.
  • payload : data sent by the application to the store.

In our case we have four actions whose types have been described above.

  • GetAccounts: Does not have a payload, it allows you to indicate that you want to retrieve the list of accounts.
  • GetAccountsSuccess: Has a payload with the list of accounts once the function of our service has been executed.
  • SelectAccount: Has a payload that matches the selected account.
  • EthError: Has a payload that matches the error returned by web3.

Finally we export the list of classes in an AccountsActionstype.

Reducers

Let’s now look at our eth.reducers.ts

This is where magic happens. The role of the reducer is to modify the state of the application according to the actions received by the store.

Reducer

We start by defining the structure of our state :

  • selected: The account currently in use
  • accounts: The list of available accounts.

Then create an initial state with the two null values.

The reducer allows to manage the actions created previously and to modify the state accordingly. Each time the store receives an action, the reducer looks at its type and changes the state immutably. Note the {…state } syntax, it allows to reproduce the `state` object without keeping its reference, which makes the state immutable.

Warning:
Note the default case that returns the state. It is necessary to manage the default case. If you have several reducers in your application the state managed by this reducer will be destroyed each time another action is managed by the store.

Ethereum Global State

At the end of our file we define the global state of the application. Here we only have one reducer, but in a real world application you would have multiple reducers that manage several kind of objects (transactions, contracts, …).

This reducer will be added to our StoreModule in ethereum.module.ts.

Last part in the next article.

You can find the source code here :
https://github.com/B2-Expand/angular-ethereum-boilerplate

--

--

GrandSchtroumpf
B2Expand

I co-founded DappsNation, a Blockchain studio that build awesome decentralized applications. I also work at the Ethereum Foundation for the Remix project.