@StateRepository

@StateRepository - This is a decorator that provides an extension of the functionality of NGXS states, thanks to which you get access to the internal mechanism of the NGXS.

By default, you can inherit from abstract classes that give you different benefits:

  • NgxsDataRepository<T> a standard repository class that gives you control over your state.

import { NgxsDataRepository } from '@angular-ru/ngxs/repositories';
import { StateRepository } from '@angular-ru/ngxs/decorators';

@StateRepository()
@State({
    name: 'app',
    defaults: {}
})
@Injectable()
export class AppState extends NgxsDataRepository<AppModel> {}
Method/PropertyReturn typeDescription

state.name

string

State name

state.initialState

T

Default state value

state.getState()

T

Current state value

state.snapshot

T

Memoized state value (getter)

state.patchState(Partial<T | Immutable<T>)

void

Ability to update part of the state

state.setState(Immutable<T> | T | (state: T) => T | Immutable<T>)

void

Overwrite state

state.reset()

void

Reset state with default state value

dispatch(actions: ActionType | ActionType[])

void

Standard dispatch method

state.state$

Observable<T>

State data stream that you can subscribe to changes

  • NgxsImmutableDataRepository<T> it's the descendant of the NgxsDataRepository class, however it gives you completely deep immutable control over your state and prevents the code from compiling if the user tries to mutate something in the state. It is recommended to use it if you understand what immutability of objects is.

import { NgxsImmutableDataRepository } from '@angular-ru/ngxs/repositories';
import { StateRepository } from '@angular-ru/ngxs/decorators';

@StateRepository()
@State({
    name: 'app',
    defaults: {}
})
@Injectable()
export class AppState extends NgxsImmutableDataRepository<AppModel> {}
Method/PropertyReturn typeDescription

state.name

string

State name

state.initialState

Immutable<T>

Default state value

state.getState()

Immutable<T>

Current state value

state.snapshot

Immutable<T>

Memoized state value (getter)

state.patchState(Partial<T | Immutable<T>)

void

Ability to update part of the state

state.setState(Immutable<T> | T | (state: Immutable<T>) => Immutable<T>)

void

Overwrite state

state.reset()

void

Reset state with default state value

dispatch(actions: ActionType | ActionType[])

void

Standard dispatch method

state.state$

Observable<Immutable<T>>

State data stream that you can subscribe to changes

  • NgxsDataEntityCollectionsRepository<V, K> a standard repository class for entity which provides an API to manipulate and query entity collections.

@StateRepository()
@State({
    name: 'article',
    defaults: createEntityCollections()
})
@Injectable()
class ArticleEntitiesState extends NgxsDataEntityCollectionsRepository<Article> {}
Method/PropertyReturn typeDescription

state.name

string

State name

state.initialState

NgxsEntityCollections<V, K>

Default state value

state.getState()

NgxsEntityCollections<V, K>

Current state value

state.snapshot

NgxsEntityCollections<V, K>

Memoized state value (getter)

state.reset()

void

Reset state with default state value

state.state$

Observable<NgxsEntityCollections<V, K>>

State data stream that you can subscribe to changes

state.entities()

EntityDictionary<K, V>

Entities dictionary

state.entitiesArray()

V[]

Entities array

state.entities$

Observable<EntityDictionary<K, V>>

Observable of entities dictionary

state.entitiesArray$

Observable<V[]>

Observable of entities array

dispatch(actions: ActionType | ActionType[])

void

Standard dispatch method

state.addOne(entity: V)

void

Add one entity to the collection

state.addMany(entities: V[])

void

Add multiple entities to the collection

state.setOne(entity: V)

void

Add or Replace one entity in the collection

state.setMany(entities: V[])

void

Add or Replace multiple entities to the collection

state.setAll(entities: V[])

void

Replace current collection with provided collection

state.updateOne(update: EntityUpdate<V, K>)

void

Update one entity in the collection. Supports partial updates

state.updateMany(updates: EntityUpdate<V, K>[])

void

Update multiple entities in the collection. Supports partial updates

state.upsertOne(entity: V)

void

Add or Update one entity in the collection. Supports partial updates

state.upsertMany(entities: V[])

void

Add or Update multiple entities in the collection. Supports partial updates

state.removeOne(id: K)

void

Remove one entity from the collection

state.removeMany(ids: K[])

void

Remove multiple entities from the collection

state.removeAll()

void

Remove all entities from the collection

Composition

You can compose multiple stores together using class inheritance. This is quite simple:

abstract class CommonCounter extends NgxsDataRepository<number> {
    @DataAction()
    public increment() {
        this.ctx.setState((state: number) => ++state);
    }
}

@StateRepository()
@State({
    name: 'a',
    defaults: 0
})
@Injectable()
class A extends CommonCounter {}

@StateRepository()
@State({
    name: 'b',
    defaults: 0
})
@Injectable()
class B extends CommonCounter {}

@Component({
    selector: 'app'
    // ..
})
class AppComponent implements OnInit {
    constructor(public a: A, public b: B) {}

    public ngOnInit(): void {
        console.log(a.snapshot); // 0
        console.log(b.snapshot); // 0
    }
}

Now when A or B is invoked, it will share the actions of the CommonCounter. Also, all state options are inherited if add @State under CommonCounter.

@State({
    name: 'commonCounter',
    defaults: 0
})
@Injectable()
class CommonCounterState extends NgxsDataRepository<number> {
    @DataAction()
    public increment() {
        this.ctx.setState((state: number) => ++state);
    }
}

@StateRepository()
@State({ name: 'a' })
@Injectable()
class A extends CommonCounterState {}

@StateRepository()
@State({ name: 'b' })
@Injectable()
class B extends CommonCounterState {}

@Component({
    selector: 'app'
    // ..
})
class AppComponent implements OnInit {
    constructor(public a: A, public b: B) {}

    public ngOnInit(): void {
        console.log(a.snapshot); // 0
        console.log(b.snapshot); // 0
    }
}

Last updated