DEV Community

Maxim Pavlov
Maxim Pavlov

Posted on

3 1

State-driven development of user interface components

I often see code describing the state of the user interface that needs to be simplified.

Let's see code that outputs a list of users.

  <ng-container *ngIf="isLoading && !error">Loading...</ng-container>
  <ul *ngIf="users && users.length && !error">
    <li *ngFor="let user of users">{{user.name}}</li>
  </ul>
  <ng-container *ngIf="!error && !loading && users && !users.length">Nothing found</ng-container>
  <ng-container *ngIf="!isLoading && error">{{error.message}}</ng-container>

This code is just awful. It is difficult to read and maintain.
I prefer another way. I used to read about the theory of finite-state machines. The state machine has a finite set of states, and it is in one of these states at each moment.

We have four states of the user's list:

  1. Loading
  2. Users loaded
  3. Users were loaded with errors
  4. Users were not founded

Let's describe the state with a discriminated union.

type State =
  | { status: 'loading' }
  | { status: 'success', data: IUser[] }
  | { status: 'failed', error: Error }
  | { status: 'not-founded' }

Let's rewrite view logic.

  <ng-container *ngIf="state.status === 'loading'">Loading...</ng-container>
  <ul *ngIf="state.status === 'success'">
    <li *ngFor="let user of state.data">{{user.name}}</li>
  </ul>
  <ng-container *ngIf="state.status === 'not-found'">Nothing found</ng-container>
  <ng-container *ngIf="state.status === 'failed'">{{state.error.message}}</ng-container>

You can make the state type universal by using generics.

type State<TSuccessData> =
  | { status: 'loading' }
  | { status: 'success', data: TSuccessData }
  | { status: 'failed', error: Error }
  | { status: 'not-founded' }
type UsersListState = State<IUser[]>;

This code is more reading and self-documenting. Presently your IDE gives better hints for you.
Code completion example
Code completion example
Your team will be grateful to you.

P.S. Sorry for my English. It is my first article in English.

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay