It's quite possible that I've set up my Akita store incorrectly but I have followed the docs pretty closely.
I'm setting some routerLink
s to populate dynamically from a store (app behavior depends on updating routes as a user navigates)
Inside the subscription that returns the app state from which I derive my new routes, if I assign the returned object to my component parameter, I get the dreaded ExpressionChangedAfterItHasBeenCheckedError
Weirdly, if I instead assign a static object to that property inside the subscription, I don't get the error (but the value is static, not what I need)
I was able to get it to work with .detectChanges()
but my impression was that Akita handles change detection for us so I'm super confused (and would like to not have to manually detect changes every time I sub to a store query)
The code that works (in the nav bar):
ngOnInit(): void {
this.getRouteParams();
this.appQuery.appState$.subscribe(next => {
this.app = next;
this.change.detectChanges();
//setting this.app = a static object instead of the prior 2 lines also works "fine"
});
The code that sets the state (in one of the navigable components):
ngOnInit(): void {
this.route.params.subscribe(
(params: Params) => {
this.slug = params['slug'] ? params['slug'] : '';
this.appService.updateTab('activeRosterSlug',this.slug);
}
)
}
query.ts:
import { Injectable } from '@angular/core';
import { Query } from "@datorama/akita";
import { AppState, AppStore } from './store'
@Injectable({providedIn: 'root'})
export class AppQuery extends Query<AppState> {
constructor(private appStore: AppStore){
super(appStore)
}
appState$ = this.select();
}
}
store.ts:
import { Injectable } from '@angular/core';
import { Store, StoreConfig } from '@datorama/akita';
export type AppState = {
activeRosterSlug: string,
activeMatchSlug: string;
activeEventSlug: string;
activeManifestSlug: string;
maximixed: boolean;
footerExp: boolean;
}
export const getInitialState = () => {
return{
activeRosterSlug: '',
activeMatchSlug: '',
activeEventSlug: '',
activeManifestSlug: '',
maximixed: false,
footerExp: false
}
}
@Injectable({providedIn: 'root'})
@StoreConfig({name: 'appStore'})
export class AppStore extends Store<AppState> {
constructor(){
super(getInitialState())
}
}
service.ts:
import { Injectable } from '@angular/core';
import { AppStore } from './store';
@Injectable({providedIn: 'root'})
export class AppService {
constructor(private appStore: AppStore) {}
updateTab(tabName: string, tabId) {
let update = {}
update[tabName] = tabId;
this.appStore.update(update);
}
}