ChrisGeo
ChrisGeo

Reputation: 3917

@ngrx/store not subscribing correctly to select

I have created the following Angular 2 application with @ngrx/store, @ngrx/efffects

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    SharedModule,
    StoreModule.provideStore({mainStoreReducer}),
    EffectsModule.run(MainEffects)


  ],
  providers: [
    StompService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

export interface State {
  counter: number;
  persons: any[];
  personsLoaded : boolean;
}

export const initialState: State = {
  counter: 10,
  persons: [],
  personsLoaded: false,
};


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  title = 'app works!';
  data$;
  persons$;
  personForm: Person = <Person>{};

  persons = [];
  // state: State;

  constructor(private store: Store<State>,
              private http: Http,
              private stomp: StompService)  {
    // console.log(`We have a store! ${store}`);
    this.store.dispatch(CounterService.requestUsers);

    this.persons$ = store.select((state: State) => state.persons);
    this.data$ = store.select((state: State) => `Data is: ${state.counter}`);

  }
}

export interface Person {
  name: string,
  surname: string
}

<ul>
    <li *ngFor="let person of persons$ | async; let i = index">{{i}}. {{person.name}} {{person.surname}}</li>
</ul>

@Injectable()
export class MainEffects {

  constructor(private action$: Actions,
              private http: Http) {
  }

  @Effect() users$ = this.action$.ofType(CounterService.REQUEST_USERS)
    .switchMap(() => this.http.get("api/persons"))
    .map(res => res.json())
    .map(json => json._embedded.persons)
    .do(json => console.log(json))
    .switchMap(result => Observable.of(CounterService.receivedUsers(result)));
}


export const mainStoreReducer: ActionReducer<State> =
  (state = initialState, action: Action) : State => {

    console.log(`Action came in ! ${action.type}`);

    switch (action.type) {

      case CounterService.RECEIVED_USERS: {
        return {
          counter: state.counter,
          persons: action.payload,
          personsLoaded: true
        };
      }
      case CounterService.REQUEST_USERS: {
        console.log("requested users");
        return state;
      }
      default: {
        return state;
      }
    }
  };

Ok so there seems to be a problem with these lines:

`StoreModule.provideStore({mainStoreReducer})` and  

this.persons$ = store.select((state: State) => state.persons);

When I use mainStoreReducer in {} the select doesn't seem to work correctly. However if I do StoreModule.provideStore(mainStoreReducer) then it works miraculously!. Obviously I can't do only that because that's just one reducer, so on a normal project I would have multiple.

Anyone have an idea what's going wrong. Please have a look at the github project directly if you like https://github.com/cgeo7/ngrx_tests_websockets_spring-boot It builds normally.

EDIT: I have made those modifications, but I see that the problem is that state has the reducer Object at the first level of the hierarchy and it contains the actual state. Additionally, if I add a second reducer this is never initialized like mainStoreReducer. There's something fishy here

enter image description here

Upvotes: 0

Views: 848

Answers (2)

fastAsTortoise
fastAsTortoise

Reputation: 641

you need (key, value) pair for provide store so you can do following instead

StoreModule.provideStore( { mainStore: mainStoreReducer, anotherStore: anotherStoreReducer })

But as @coskun said you should create a separate file and combine reducers into a single reducer and then import that into you app component. Hope this will help.

Upvotes: 1

Coşkun Deniz
Coşkun Deniz

Reputation: 2279

First you need to export your reducers into single "reducer", after that you should do: StoreModule.provideStore(reducer).

Check this repo: https://github.com/onehungrymind/angular-applied-dashing/blob/master/src/app/common/reducers/index.ts

Upvotes: 2

Related Questions