0
votes

I want to fetch the current state of a ngrx store without using subscribe. I tried some of the solutions I found but they usually gave me an undefined result, perhaps because my store is not set up correctly. I have managed to achieve this but I do not think that this is the best way of doing it. I am currently able to fetch the state like so:

I am defining a store instance in the component class:

ngStore: any;

In the constructor parameters I'm creating an instance of the specific store I want to use:

private calculatorSliderStore: Store<CalculatorSliderState>,

I am initializing the store instance in the constructor:

this.ngStore = this.calculatorSliderStore.pipe(select(getCalculatorSliderState));

I log the current state of the store:

console.log(this.ngStore.source.actionsObserver._value.payload);

This is all working but I do not think that this is the correct way of doing it. Can anyone confirm this and offer a better solution?

1

1 Answers

0
votes

The async pipe is probably the best way to accomplish this, though it subscribes in the background, so you'll still get changes pushed from the store to your component. If you'd prefer the value didn't change, you can add on a take(1) from rxjs to stop listening after the first value. (The store will immediately emit as soon as it is subscribed to).

Typescript:

@Component({ ... })
export class MyComponent {
  dynamicSliderState$ = this._store.pipe(select(selectSliderState));
  singleSnapshotOfSliderState$ = this._store.pipe(
    select(selectSliderState),
    take(1)
  );

  constructor(private _store: Store) {}
}

Template:

This one will change when store state changes:
<pre>{{ dynamicSliderState$ | async | json }}</pre>

This one will be set on construction and then no longer update:
<pre>{{ singleSnapshotOfSliderState$ | async | json }}</pre>

To use the value emitted from the observable elsewhere in the
template, we can create a reference to it using `*ngIf` or
ngrx's `*ngrxLet` pipe:

<ng-container *ngIf="dynamicSliderState$ | async as foo">
  This looks the same as the first `pre` above: 
  <pre>{{ foo | json }}</pre>
</ng-container>

Generally, you'd want to use this reference pattern where you can to limit subscriptions - especially multiple subscriptions on the same observable. The risks of multiple subscriptions is heavily lessensed when using ngrx/store though.