Using the Angular 2 Http client in order to rehydrate application state in a ngrx meta reducer

1.1k views Asked by At

I need to be able to use the Angular 2 Http client right from the @NgModule's imports. This is required in order to rehydrate application state by fetching data from the backend using the Http client.

Here is how my sample application is configured:

@NgModule({
  imports: [
    CommonModule,
    BrowserModule,
    HttpModule,
    ComponentsModule,
    RouterModule.forRoot(routes, { useHash: true }),
    StoreModule.provideStore(reducer),//See below for definition of reducer
    ...

Here is the definition for the reducer function used above:

const initialState: State = {
  ids: [],
  loading: false,
  query: ''
};

export function reducer(state = initialState, action: book.Actions): State {
  switch (action.type) {
    case book.ActionTypes.SEARCH: {
      const query = action.payload;
      ...

I therefore need to somehow use the Http client to populate the initialState constant above. Is this possible? If so how?

The trouble is that I need to somehow inject the Http client as the app is being bootstrapped...

This is a requirement as it seems the library I use i.e. ngrx (https://github.com/ngrx) depends on reducers defined at the time of application bootstrap.

I would be extremely grateful for help on this one...

1

There are 1 answers

0
Pavel Gurecki On

You can't set initialState constant with async operation - it must be available immediately.

Even if you'd manage to inject Http to initialState provider (yes, it has a factory identified by INITIAL_STATE token in ngrx/store source) it won't wait for async operation (get your data from server) before returning initialState - that's limitation from angular's sync factories.

Solutions:

  1. Add REHYDRATE action and dispatch it as soon as possible (on bootstrap), have an effect which would get your data from server and set it in state with REHYDRATE_SUCCESS action.
  2. Inject data to your index.html as a global var from your backend (prefetching), read initialState from there.