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.

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

👋 Kindness is contagious

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

Okay