mwilson
mwilson

Reputation: 12960

NgRx Get value without subscribing

I am working my way through some ngrx tutorials and I think I'm starting to get my brain wrapped around it.

What I don't understand is how to do something as simple as getting a value from the Store:

Goal: Get a value from the store without having to subscribe to it. IE: store.myStoreProperty or store.getValue(<selector>) or ?

From what I understand the only way to grab a value from the store is to do something like this:

  private readonly _store: Store<ApplicationState>;
  // ...
  this._store.select(state => state.currentUser).subscribe(user => {
    if (!user) { return; }
    // ...
  });

Question: Is there any possible way to "instantly" get a value from the store without having to subscribe?

I might just be having trouble wrapping my brain around selectors but I kind of thought that was what they were for. Example from the docs:

import { createSelector } from '@ngrx/store';

export interface FeatureState {
  counter: number;
}

export interface AppState {
  feature: FeatureState;
}

export const selectFeature = (state: AppState) => state.feature;

export const selectFeatureCount = createSelector(
  selectFeature,
  (state: FeatureState) => state.counter
);

In this example, I was thinking that I could just call selectFeature or pass it into this._store.select(selectFeature) to get the actual value, but it returns an observable (and thus wanting you to subscribe to it).

My main use case here is that I want to access current user info throughout the lifecycle of my app. I have an effect that is getting that information from the server, and it all works great. However, I am a little confused on how I can simply just access the value from the store without having to sprinkle .subscribe everywhere.

And yes, I have seen this but it doesn't help me.

Upvotes: 8

Views: 13707

Answers (3)

Alexander Bukhtatyy
Alexander Bukhtatyy

Reputation: 11

You can use method of state - getValue, to get current value of state

const value: string | undefined = SELECTORS.selectValue(this.state.getValue());

Upvotes: 0

James D
James D

Reputation: 2301

How about you add your own subscribe function and call that every time?

  getValue(obj: Observable<any>){
    let value: any;
    obj.subscribe(v => value = v);
    return value;
  }


  showme(){
    console.log(this.getValue(this.user$));     // single value => works
    console.log(this.getValue(this.projects$)); // array => works
  }

Do note that you lose the magic of observables, so when the value changes, it won't update you frontend etc... You will just have the value of the moment in time when asked for the value.

refence to stackblitz demo

The way you're calling you selectors seems wrong you should be importing them like this:

import * as fromAuth from '../../auth/state/reducers';
import * as fromData from '../../data/state/reducers';

And you build your constructor like this:

constructor(private store: Store<fromAuth.State & fromData.State>) {

Your select could then be like this,

this.user$ = store.pipe(select(fromAuth.getUser));
let user = this.getValue(store.pipe(select(fromAuth.getUser))); // this would get you the current user value

Check out the ngrx example app specifically this index page I'm referencing to, to check out selectors. Check out this sample on how they use the selectors and import the state

Normally you build containers and components. You build a container responsible for getting the data from the store, which you then pass with the async pipe to the next container or component which is responsible for the display. With ngOnChanges you can detect changes and update the frontend accordingly.

Upvotes: 2

Tony
Tony

Reputation: 20132

You can use async pipe like this

export class MyComponent implements OnInit {
    data$: Observable<any>;

    constructor(private store: Store<ApplicationState>) {}

    ngOnInit() {
        this.data$ = this.store.pipe(select(yourSelector));
    }
}

Then in your view

<app-data [data]="data$ | async"></app-data>

Upvotes: 0

Related Questions