Base Class for Akita Entities

jengfad

Jennifer Fadriquela

Posted on June 14, 2020

Base Class for Akita Entities

If you are using Akita for state management, this article might be helpful to you.

// BaseEntityService.ts
import { Observable } from 'rxjs';
import { BaseQuery } from './BaseQuery';
import { EntityStore, EntityState } from '@datorama/akita';
import { tap, delay } from 'rxjs/operators';

export abstract class BaseEntityService<TParams, TView, TResult> {

    constructor(
        protected query: BaseQuery<TView, TParams>,
        protected entityStore: EntityStore<EntityState<TView>, TView>
        ) {
    }

    protected abstract getFromApi(params: TParams): Observable<TResult>;
    protected abstract getFromStore(params: TParams): Observable<TResult>;

    protected selectFromStore(params: TParams): Observable<TView> {
        return this.query.selectData(params).pipe(
            delay(1), // if removed, ui will not update with current data
        )
    }

    get(params: TParams): Observable<TResult> {
        return this.toggleLoading(
            () => {
                if (!this.query.hasData(params))
                    return this.getFromApi(params);
                else
                    return this.getFromStore(params);
            }
        );
    }

    private toggleLoading<TResult>(o: () => Observable<TResult>) {
        this.entityStore.setLoading(true);
        return o().pipe(
            tap((x) => {
                this.entityStore.setLoading(false);
            })
        )
    }
}
Enter fullscreen mode Exit fullscreen mode

BaseEntityService handles abstraction for getting data from api or store. It also implements custom setting of entity loading property via toggleLoading.

// BaseQuery.ts
import { EntityState, QueryEntity } from "@datorama/akita";
import { filter } from 'rxjs/operators';

export abstract class BaseQuery<TView, TParams> extends QueryEntity<EntityState<TView>, TView> {
    selectData(params: TParams) {
        const key = JSON.stringify(params);
        return this.selectEntity(key).pipe(
            filter(x => !!x)
        )
    }

    selectDataNullable(params: TParams) {
        const key = JSON.stringify(params);
        return this.selectEntity(key);
    }

    hasData(params: TParams) {
        const key = JSON.stringify(params);
        return this.hasEntity(key);
    }
}
Enter fullscreen mode Exit fullscreen mode

BaseQuery contains custom selection of existing store data. In our app, we use stringified parameters as keys.

💖 💪 🙅 🚩
jengfad
Jennifer Fadriquela

Posted on June 14, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Base Class for Akita Entities
typescript Base Class for Akita Entities

June 14, 2020