Reputation: 12960
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
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
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.
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
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