Search code examples
javascriptangulartypescriptrxjsngrx

How to use @ngrx/store in component?


My understanding after reading the documentation is that in order to obtain values from an NgRx store, we have to use selectors. So far, I've had luck doing that, only with a small issue regarding typing, which makes me worried if my implementation is incorrect in any way.

So, let's say I want to retrieve a number value from the store, id for example. In my componentName.component.ts I would access this value like this:

id$ = this.store.select(selectId);

where selectId is defined from another file as:

export const selectData = (state: AppState) => state.data;

export const selectId = createSelector(
  selectData,
  (state: DataState) => state.id,
)

I am able to access id$ in my HTML component easily by doing {{id$ | async}}, but accessing it from the component class itself has proven a bit more difficult. For starters, the variable type is Observable<number> instead of just number, and that makes it hard to use it in cases where it needs to be of number type, such as when comparing it:

  ngOnInit(): void {
    console.log(this.id$ === 0);
  }

The TypeScript error I get from the code above is:

TS2367: This condition will always return 'false' since the types 'number' and 'Observable ' have no overlap.

And console-logging id$ itself confirms that it is indeed of Observable type, so this leads me to believe I am doing something wrong, but I'm unsure exactly what. Any help is appreciated!!!


Solution

  • id$ is an Observable, and you can access its value by subscribing to it from the component class using subscribe function, or from the component template using async pipe.

    In Component Class:

    ngOnInit(): void {
      this.id$.subscribe(id => console.log(id));
    }
    

    In Component Template:

    <span>{{ id$ | async }}</span>
    

    Check the official docs of Angular about Observable(s):

    https://angular.io/guide/observables