Search code examples
angularrxjsngrx-store

What is the best practice/right way to include rxjs store in angular2/4, is it supposed to be in bootstrap or import?


When I read about ngrx, I see different ways of including the store:

One way I see is to include in imports:

@NgModule({
    imports: [
        ... omitted
        StoreModule.provideStore(AppReducer),
    ],
    declarations: [
        AppComponent
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

The other way I've seen is to include it in bootstrap:

import {bootstrap} from 'angular2/platform/browser';
import {App} from './src/app';
import {provideStore} from '@ngrx/store';
import {ItemsService, items, selectedItem} from './src/items';
bootstrap(App, [
  ItemsService, // The actions that consume our store
  provideStore({items, selectedItem}) // The store that defines our app state
])
.catch(err => console.error(err));

Which is correct and/or is the accepted best practice? Why?

I look at a random app.module.ts file from a project without rxjs store and am wondering where it should go properly in a file like this:

https://github.com/AngularClass/angular2-webpack-starter/blob/master/src/app/app.module.ts

Appreciate optionally any any references to how "current" May 2017 angular2/4 applications should be organized in respect to integration with RxJS.


Solution

  • I like to keep my AppModule as clean as possible.

    One day, while I was thinking a lot about module structure and SPA design with Angular I've seen a Tweet from Wassim Chegnam. It was about modules with Angular, and he drew this : enter image description here

    I really liked that idea of having 3 main modules :
    - features
    - shared
    - core

    How to use them :

    • Features for everything directly related to our app
    • Shared for everything that we want to easily import from everywhere
    • Core for everything related to the project configuration (mostly modules with forRoot)

    So in your case, I'd put the StoreModule.provideStore(AppReducer) in CoreModule. (example)

    Obviously, you can go with a simpler module structure but after I used that way of doing things in a large application and a small/medium app to demo how to use ngrx (Pizza-Sync), it felt like a good thing =).

    In the end, I do have an AppModule really clean :

    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule,
        CoreModule,
        SharedModule,
        AppRoutingModule
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    and if I need to use angular-universal I'd have no problem to switch from app.module.ts to app.module.universal.ts.

    Edit: May, 14th (2017)
    I released a couple of days ago an ngrx starter on Github where I try to describe all of that and include a lot of good things I've been discovering for the last 8 months. It might interest some of you: https://github.com/maxime1992/angular-ngrx-starter