Part I. What does NGXS offer? 🌈

Ivanov Maxim
NGXS Stories
Published in
7 min readOct 6, 2019

Introduction

Last time we talked about how to work with immutable data and how to store data in NGXS (part I, part II, part III). Today we will talk about what does NGXS offer and when need to choose native RxJS. In the following parts, we will discuss many interesting topics related to NGXS. But before diving in, let’s look at the history of state management and where NGXS came from.

Part I. What does NGXS offer?

  • 🐼 I. What is Redux?
  • 💥 II. Angular + RxJS
  • 🦅 III. Angular + NGXS

Next time we talk about:

Part II. Is Flux the foundation of our architecture?
Part III. How does NGXS compare to NgRx?
Part IV. How different or similar are the implementations of NGXS, NgRx?
Part V. How does NGXS compare to Akita?

🐼 What is Redux?

NGXS is a state management framework that implements the CQRS design pattern, just like Redux.

Redux is a predictable state container for JavaScript apps. Let’s look at a simple example:

Simple app (Redux + vanilla JS)
index.html

Redux makes it easy to manage the state of your application. Another way of looking at this — it helps you manage the data you display and how you respond to user actions.

Redux architecture:

  • Actions (they are the only way you can send data from your application to your Redux store. The data can be from user interactions, API calls or even form submission);

Actions are sent using store.dispatch() method. Actions are plain JavaScript objects that must define a type property that describes what the action does. They can optionally define a payload property that contains information necessary to perform the action.

{ 
type: "LOGIN",
payload: {
username: "foo",
password: "bar"
}
}
  • Reducers (reducers are pure functions that take the current state of an application, perform an action and return the new state. These states are stored as objects and they specify how the state of an application changes in response to an action sent to the store);
  • Store (the store holds the application state. There is only one store in any Redux application. The store lets you read from state, dispatch actions to modify state, and register or unregister to state changes).

When you first started writing Angular applications you may have thought, why do we need Redux at all? Many problems are solved without it. In many ways, you’d be right, but not everywhere.

💥 Angular + RxJS

Angular + RxJS (simple app)

RxJS is a javascript library that brings the concept of “reactive programming” to the web.

Reactive programming is just a different way of building software applications. Essentially, your software is built to “react” to changes that happen like click events, data being fetched, instead of the typical way of writing software where we explicitly write “imperative” code to handle those changes.

As you can see, our Angular code is elegant. You can easily manage the state of your application or component using a reactive approach and you will be happy.

Coding is all about problem-solving and finding the right tools to fix the right problems. In the case of RxJS, the problem being solved is the ability to handle asynchronous or synchronous calls with multiple events. But what does that mean exactly?

Imagine that you are writing a function that passes data along a series of Ajax requests. What happens when there is an error in the middle of the series? If you are using vanilla javascript, it would be difficult and cumbersome to cancel the remaining requests and return the error. Rather than passing the error through the series of functions, it would be more efficient to catch the error ASAP and update the view without running through the remaining useless Ajax requests.

Javascript promises can handle this type of error handling more elegantly, but RxJS takes the concept of funneling consecutive actions to the next level. A promise can only handle returning a single value, limiting its use cases. Additionally, promises are not cancellable, meaning that it has the potential to block the thread and use up unnecessary resources (important consideration for resource constrained devices).

RxJS offers a robust solution to these limitations by offering more than one channel of communication to simplify the handling of a multi-step event in an efficient way. RxJS gives developers the ability to treat anything that needs to fire an event as a single shaped thing. When everything is the same shape, it becomes very easy to combine, merge and query those things resulting in a very powerful tool (such NGXS, NgRx, etc).

🦅 Angular + NGXS

NGXS uses TypeScript functionality to its fullest extent and because of this it will feel more familiar for Angular developers. NGXS tries to make things as simple and accessible as possible. There can be a lot of boilerplate code in state management, thus a main goal of NGXS is to reduce boilerplate allowing you to do more things with less. It is also not necessary to be super familiar with RxJs.

Angular + NGXS (simple app)

count.state.ts

count.actions.ts

app.component.ts

😋 I think your first impression will be just that:

But in real applications, you are unlikely to come across a class like CountState. It would not make sense to use NGXS state for something so trivial. It’s important to understand what belongs in global state.

Angular framework are built with a way for components to internally manage their state without any need for an external library or tool. It does well for applications with few components but as the application grows bigger, managing states shared across components becomes a chore.

In an app where data is shared among components, it might be confusing to actually know where a state should live. Ideally, the data in a component should live in just one component. So sharing data among sibling components becomes difficult. However, if your app is going to consist of mostly simple actions such as UI changes, these don’t really have to be a part of the NGXS (Redux Store) and can be handled at the component level.

Why you should use NGXS instead of native RxJS?

  • If you want to use immutable data “out of the box” for application.
  • The store and unidirectional data flow greatly reduce coupling between parts of your application. This reduced coupling reduces the complexity of your application since each part only cares about specific states.
  • Since this pattern (Redux) is widely adopted and simple, it is easy for new team members experienced with state management to ramp up quickly.
  • You can persist some of the app’s state to local storage and restore it after a refresh. This can be really nifty.
  • Debuggable for days. By logging actions and state, it is easy to understand coding errors, network errors and other forms of bugs that might come up during production.
Debuggable for days

It would be difficult to debug the application state if it was written using only native RxJS. Can you recall the last time you could clearly say what behavior your application has?

Why you should use native RxJS instead NGXS?

  • NGXS (Redux) can be initially difficult to grasp.
  • If you don’t need to have a single store for the synchronization of changes across the app, but would rather have many small encapsulated and independent reactive states in your application.
  • NGXS uses a BehaviorSubject for storing state. You may want to use any of the other types of Observables (Subject, AsyncSubject, ReplaySubject) provided in RxJS for your particular goals.
  • If you want to control the store and management of data in your application yourself.

--

--

Ivanov Maxim
NGXS Stories

Code 🤖, Bike 🚵 and Music 🎶 Teams: @splincodewd ★ @Angular-RU ★ @ngxs ★ github.com/splincode