My service class, before calling a web service, needs to get a property called dataForUpdate
from my state. Currently, I\'m doing it like this:
@ngrx/store
extends BehaviorSubject and it has a value
property you can use.
this._store.value
that will be the current state of your app, and from there you can select properties, filter, map etc...
update:
Took me a while to figure what's what in your example (: To get current value of dataForUpdate
, you can use:
let x = this._store.value.StateReducer.dataForUpdate;
console.log(x); // => { key: "123" }
With the update to version 2, value
was removed as described in docs:
The APIs for synchronously pulling the most recent state value out of Store have been removed. Instead, you can always rely on
subscribe()
running synchronously if you have to get the state value:
function getState(store: Store<State>): State {
let state: State;
store.take(1).subscribe(s => state = s);
return state;
}
the State class in ngStore is an BehaviorSubject, so we can inject it, and use it's value property to get the latest value.
constructor(private state:State<YourState>...) {
}
someMethod() {
// WHAT'S MORE: you can use your selector directly on it!
let v = yourSelector(this.state.value);
}
Not strictly a direct answer to the question, but I found this page looking for how to retrieve a single value from the store.
To achieve this, you can inject the State
object from @ngrx/store
as shown below:
import { State } from '@ngrx/store';
constructor (private state: State<AppState>) {
let propertyValue = state.getValue().path.to.state.property;
}
The state
object holds the current state in a private _value
property, accessed by the .getValue()
method.
That's works for me. You need to import Store from '@ngrx/store' and AppState is your state.
private state: AppState;
constructor(private store: Store<AppState>) { }
ngOnInit() {
this.store.select(x => this.state = x).subscribe();
}
withLatestFrom()
or combineLatest()
methods in the subscription chain give you just what you need, and are aligned with the spirit of Observables+Ngrx.
In place of the GET STATE .mergeMap()
in the code above, using withLatestFrom()
would look something like this:
...
.withLatestFrom(store$, (payload, state) => {
return {payload: payload, stateData: state.data}
} )
...
As an aside, the code in the original question appears to be managing asynchronous effects of redux actions, which is exactly what the ngrx/effects library is for. I suggest you check it out. After you get Effects wired up, the code for managing asynchronous redux actions is much cleaner. This article by Jim Lynch was also super helpful to me: The Basics of "ngrx/effects", @Effect, and Async Middleware for "ngrx/store" in Angular 2
As of v4.x we are forced to put the take
operator into the pipe like that to get it synchronous:
function getState(store: Store<State>): State {
let state: State;
store.pipe(take(1)).subscribe(s => state = s);
return state;
}