A Brief Overview

Akita is a simple and effective state management pattern, built on top of RxJS. Akita encourages simplicity. It saves you the hassle of creating boilerplate code and offers powerful tools with a moderate learning curve, suitable for both experienced and inexperienced developers alike.

In this article, we’ll create a simple eCommerce website, with a list of products on one side and filters we can apply on the other side. We’ll also create basic authentication functionality and learn how to implement some advanced caching.

This article assumes that you have at least a basic knowledge of Akita, but even if you don’t, I’m sure you’ll be able to understand the code fairly easily.

Here’s an illustration of the final result:

Let the fun begin 😎

Creating the Login Feature

The Auth Store

Akita provides two types of stores, a basic store which can hold any shape of data and an entity store which represents a flat collection of entities.

In this case, we need to use the basic store that will hold the auth state:

auth.store.ts

We created an AuthStore and provided it with the initial state. We also apply the resettable option; This means that we’ll be able to call store.reset() anytime to go back to the store’s initial state value. In our case, we’ll do it when the user logs out.

The Auth Query

The Query is a class responsible for querying the store. In our case, we work with a basic store, so we need to extend the basic Query :

auth.query.ts

The built-in select() method returns the requested slice from the state. The isLoggedIn$ property is an observable that notifies whether the current user is logged in based on a token presentation.

In addition, there are times when we want to get a store’s value without the need to subscribe. In our example, we create the isLoggedIn() method that returns a boolean which indicates whether the current user is logged in.

The Auth Service

Akita maintains a natural work process using Angular services, which encapsulate and manage asynchronous logic and update calls for the store.

Let’s see how we use the service to perform a REST call and update the store:

auth.service.ts

First, we create a login() method that makes an HTTP request to the server to verify the user’s credentials. When we get a success response, we update the store with the response data; it’s as simple as that.

Then, we add the logout() method that employs the reset functionality and rollback the state to the initial value.

We also use Akita’s persist state functionality to persist the token value in the local storage automatically, so we need to clear it when the user logs out.

main.ts

The Login Page

First, we need to create the login form:

login-page.component.html

We have two inputs — one for the user’s email and one for the password. Now, let’s see the component implementation:

In the submit() method, we check if the form is valid. If it is, we call the auth service login() method with the form value. If we get a 👍 response, we show the user a welcome message and send him to the home page. Otherwise, we display the given server error.

Creating the Products Feature

The Product Model

A common optimization nowadays is to fetch the minimum required data from the server so we can render the view as quickly as possible.

As good developers, we’ll follow this rule and create a BaseProduct type which contains the minimum required data to display each product in the list, and a Product type with the details we need for the product page:

product.model.ts

The Products Store

We need to maintain a collection of products, so we’ll use an EntityStore . You can think of an entity store as a table in a database, where each table represents a flat collection of entities.

Akita’s EntityStore simplifies the process, giving you everything you need to manage it.

Let’s see how we can use it to create a products table, i.e., an EntityStore managing a Product object:

products.store.ts

We also need to extend the store and add more properties to it. In our case, we need to save the applied filters and the user’s search term. We do this is by adding the properties type and passing the initial state in the constructor.

At this point, our application state looks like the following: