ngxs: Access different state within Action
Asked Answered
S

2

8

Is it possible to access a different state within a action?

Scenario: I have two states:

  • FilterState
  • AppState

FilterState contains an action Filter, when the filter action is triggered, then the filterService is called with the payload of the action + with a value from the AppState.

@Action(Filter)
filter(ctx, action) {
  // HOW TO GET VALUE FROM AppState

  return this.filterService.filter(action, valueFromOtherStore).pipe(
    tap(data => {
    // Do something with result
    })
  );
}

How is it possible to retrieve values from a different state to apply this value to the second param of this.filterService.filter?

Swift answered 16/7, 2018 at 9:31 Comment(0)
S
10

Shared State documentation answers the question:

To get access to a different state selectSnapshot method on store can be used: this.store.selectSnapshot(PreferencesState.getSort)

Example

@State<PreferencesStateModel>({
  name: 'preferences',
  defaults: {
    sort: [{ prop: 'name', dir: 'asc' }]
  }
})
export class PreferencesState {
  @Selector()
  static getSort(state: PreferencesStateModel) {
    return state.sort;
  }
}
​
@State<AnimalStateModel>({
  name: 'animals',
  defaults: [
    animals: []
  ]
})
export class AnimalState {
​
  constructor(private store: Store) {}
​
  @Action(GetAnimals)
  getAnimals(ctx: StateContext<AnimalStateModel>) {
    const state = ctx.getState();
​
    // select the snapshot state from preferences
    const sort = this.store.selectSnapshot(PreferencesState.getSort);
​
    // do sort magic here
    return state.sort(sort);
  }
​
}
Swift answered 16/7, 2018 at 10:44 Comment(2)
I still get undefined when using selectSnapshotContinuum
Using snapshot will return undefined if the other state is being initiated asynchronously. here is how I've solve that problem.Abilene
A
3

Selecting the snapshot will return undefined as the other state hasn't been initiated yet, I've solved the problem by using a normal select and filtering the result.

@State<PreferencesStateModel>({
  name: 'preferences',
  defaults: {
    sort: [{ prop: 'name', dir: 'asc' }]
  }
})
export class PreferencesState {
  @Selector()
  static getSort(state: PreferencesStateModel) {
    return state.sort;
  }
}
​
@State<AnimalStateModel>({
  name: 'animals',
  defaults: [
    animals: []
  ]
})
export class AnimalState {
​
  constructor(private store: Store) {}
​
  @Action(GetAnimals)
  getAnimals(ctx: StateContext<AnimalStateModel>) {
    const state = ctx.getState();
​
    // select the snapshot state from preferences
    return this.store.select(PreferencesState.getSort)
    .pipe(
       filter(sort => sort !== undefined),
       take(1),
       map(sort => {
           // do sort magic here
           return state.sort(sort);
       })
    );
​
}
Abilene answered 22/11, 2018 at 20:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.