Getting Ng/Rx component store error "MyStore has not been initialized yet" when calling patch

1k Views Asked by At

I am using NgRx component store 14.3.0.

I extend the Component store, like the following

@Injectable()
  export abstract class MyStoreBase<T extends MyStateBase> extends 
     ComponentStore<T> implements OnDestroy {

Sometimes just after creating it's owning component I am getting the error "MyStore has not been initialized yet" (MyStore being the name of my store)

I have setup code something like the following... I am using also using NgRx store, where I get some other global state, and then call my Component store methods

constructor(
private store$: Store<State>) {
 super(INITIAL_BASE_STATE as T);

 // Was getting some errors about calling patch before store was initialised, so make
 // the subscriptions async    
 setTimeout(() => this.initialise(), 100);
 }

public initialise(): void {
  // Subscribe to updated
  this.subs.sink = this.store$.select(fromApp.getConfig).pipe(filter(x => !!x)).subscribe(config => {       
  this.getData('');
});

private getData = this.effect((trigger$: Observable<string>) => trigger$.pipe(
  tap(() => {
    this.patchState((state) => ({ ...state, isRequesting: true }));
    ....
}),

So it is the call to patchState inside the tap that is causing the issue. I have used the setTimeout to try and get around this issue (but it is not enough)

This is the line where the error is occurring...

enter image description here

So, if I look for where this.isInitialized is being set I see this in the constructor (and I am passing a default state)

enter image description here

And then if we look at the initState we see..

enter image description here

So this.isInitialized is being set to true in what looks like some async call.

I thought I could subscribe to the this.stateSubject but it does not seem to be available.

My question is, how can I then know the store is ready to use?

1

There are 1 best solutions below

0
Gabriel Guerrero On

Some time ago ngrx team added new lifecycle hooks like component store ngrxOnStateInit https://ngrx.io/guide/component-store/lifecycle#eager-state-init, your initialise method should probably be the implementation of ngrxOnStateInit

public ngrxOnStateInit(): void {
  // Subscribe to updated
  this.subs.sink = this.store$.select(fromApp.getConfig).pipe(filter(x => !!x)).subscribe(config => {       
  this.getData('');
});