Akita is a fantastic and lightweight library for state management.
<namespace>
L <namespace>.store.ts
L <namespace>.service.ts
L <namespace>.query.ts
import { Injectable } from '@angular/core';
import { Store, StoreConfig } from '@datorama/akita';
import { User } from '@Models/user';
export interface UserState {
user: User;
token: string;
}
export const createInitialUserState = (): UserState => ({
user: undefined,
token: undefined
});
@Injectable({ providedIn: 'root' })
@StoreConfig({ name: 'user' })
export class UserStore extends Store<UserState> {
constructor() {
super(createInitialUserState());
}
}
import { Injectable } from '@angular/core';
import { User } from '@Models/user';
import { UserStore } from './user.store';
@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private readonly store: UserStore) {}
setUser(user: User): void {
this.store.update((state) => ({ ...state, user }));
}
setToken(token: string): void {
this.store.update((state) => ({ ...state, token }));
}
}
import { Injectable } from '@angular/core';
import { Query } from '@datorama/akita';
import { UserState, UserStore } from './user.store';
@Injectable({ providedIn: 'root' })
export class UserQuery extends Query<UserState> {
user$ = this.select((state) => state.user);
hasAuth$ = this.select((state) => !!state.token);
get snapshot(): UserState {
return this.getValue();
}
constructor(protected readonly store: UserStore) {
super(store);
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { CoreModule } from '@Core/core.module';
import { AkitaNgRouterStoreModule } from '@datorama/akita-ng-router-store';
import { AkitaNgDevtools } from '@datorama/akita-ngdevtools';
import { environment } from '@Environments/environment';
import { CoreConfiguration } from '@Types/core-configuration.contract';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
export const coreConfigurationFactory = (): CoreConfiguration => environment.coreConfig;
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
AppRoutingModule,
environment.production ? [] : AkitaNgDevtools.forRoot(), // HERE!
AkitaNgRouterStoreModule, // HERE!
CoreModule.forRoot(coreConfigurationFactory),
],
providers: [{ provide: RouteReuseStrategy }],
bootstrap: [AppComponent]
})
export class AppModule {}
@Component({
selector: 'user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.scss']
})
export class UserComponent {
constructor(private userQuery: UserQuery, private userService: UserService) {}
user$: Observable<User> = this.userQuery.user$.subscribe(); // mutable data
user: User = this.userQuery.snapshot.user; // static data
setUser(user: User) {
this.userService.setUser(user);
}
}