Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ngrx to obtain store's current state once

Tags:

angular

ngrx

Hi I was wondering if anyone know how to get a store's current state once without having to subscribe to it. I'm currently using ngrx to subscribe to the store and access its state to set a component's attribute, but since I'm subscribed this attribute is constantly refreshing. So I'm looking for a way to obtain this attribute just once so that I can display data without it refreshing constantly.

Just in case, this happens inside my component's constructor.

I've been trying something like this:

_store.select('storeData.correlationData');

When subscribing I would access like this:

_store.subscribe(
  (state) => {
    this.correlationData = state.storeData.correlationData;
  }
);

EDIT

Applciation State:

export interface ApplicationState {
  uiState: UiState;
  storeData: StoreData;
}
like image 626
Tuco Avatar asked Mar 09 '17 22:03

Tuco


Video Answer


1 Answers

You can create getState() function, put it in a shared module and import where needed. The key is to make it synchronous by using take(1) operator:

export function getState(store: any, selector: string) {
  let _state: any;
  store.take(1).subscribe(o => _state = o);
  return _state;
}

Here's more advanced version I'm using:

export function getState(store: any, selector?: any) {
  let _state: any;
  let state$: any;

  if (typeof selector === 'string' && /\./g.test(selector)) {
    state$ = store.pluck(...selector.split('.'));
  } else if (typeof selector === 'string') {
    state$ = store.map(state => state[selector]);
  } else if (typeof selector === 'function') {
    state$ = store.map(state => selector(state));
  } else {
    state$ = store;
  }
  state$.take(1)
    .subscribe(o => _state = o);
  return _state;
}

With this you can get state in few different ways:

getState(this.store) // all data in Store
getState(this.store, 'users')
getState(this.store, state => state.users)
getState(this.store, 'users.address.street') // Cool!

Use with caution!

As @Maximes pointed out in comments, you should try to use Observables directly in your code and use this method for testing.

like image 180
Sasxa Avatar answered Sep 20 '22 00:09

Sasxa