Blog>
Snippets

State History and Undo Actions with Akita

Explore how to manage state history and implement undo functionality in an Angular application using Akita's built-in state history features.
import { Injectable } from '@angular/core';
import { EntityState, EntityStore, StoreConfig, getInitialEntitiesState, EntityUIQuery, EntityUIStore } from '@datorama/akita';

export interface State extends EntityState<any> {}

@Injectable({ providedIn: 'root' })
@StoreConfig({ name: 'history' })
export class HistoryStore extends EntityStore<State> {
  constructor() {
    super(getInitialEntitiesState(), { historyLimit: 10 }); // Configure the history limit
  }
}
This code sets up an Akita EntityStore for managing the state history. The `historyLimit` option specifies the number of states to maintain in the history for undo operations.
import { Injectable } from '@angular/core';
import { QueryEntity } from '@datorama/akita';
import { HistoryStore, State } from './history.store';

@Injectable({ providedIn: 'root' })
export class HistoryQuery extends QueryEntity<State> {
  constructor(protected store: HistoryStore) {
    super(store);
  }
}
This code establishes a QueryEntity that will be used to select data from the HistoryStore and to access the state history.
import { Component } from '@angular/core';
import { HistoryStore, HistoryQuery } from './history.service';

@Component({
  selector: 'app-undo-button',
  template: '<button (click)="undo()" [disabled]="!hasPast$ | async">Undo</button>'
})
export class UndoButtonComponent {
  hasPast$ = this.historyQuery.selectHasPast();

  constructor(private historyStore: HistoryStore, private historyQuery: HistoryQuery) {}

  undo() {
    if (this.historyQuery.hasPast()) {
      this.historyStore.undo();
    }
  }
}
This code snippet defines an Angular component with a button for the undo action. The button is enabled or disabled based on if there are past states available. Clicking the button invokes the `undo` method which causes the HistoryStore to revert to the previous state.
/* CSS for the Undo Button */
button:disabled {
  background-color: #ccc;
  color: #fff;
  cursor: not-allowed;
}
button {
  background-color: #007bff;
  color: #fff;
  border: none;
  padding: 10px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  transition-duration: 0.4s;
  cursor: pointer;
}
button:hover {
  background-color: #0069d9;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
This CSS styles the undo button with a disabled state style, making it visually clear when the button cannot be clicked. It also includes hover effects for better user interaction experience.