简体   繁体   中英

Error with ngrx-store imported lazily

I'm kind of newbie developing Angular applications. For now, I have a simple application which works fine with services but I'm trying to use ngrx/store to control some events.

Well, I don't want to use ngrx/store on eagerly components but lazily. The structure of the project is:

app 
| --control-panel
     |--spaces

App is the root which lazily loads control-panel which lazily loads spaces.

The error I'm getting does not help me at all. Here is the error:

ERROR Error: Uncaught (in promise): Error: StaticInjectorError[ReducerManager]: StaticInjectorError[ReducerManager]: Null InjectorError: No provider for ReducerManager!

Here is the relevant code:

package.json

{
  "name": "condo-control",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^5.0.1",
    "@angular/common": "^5.0.1",
    "@angular/compiler": "^5.0.1",
    "@angular/core": "^5.0.1",
    "@angular/forms": "^5.0.1",
    "@angular/http": "^5.0.1",
    "@angular/platform-browser": "^5.0.1",
    "@angular/platform-browser-dynamic": "^5.0.1",
    "@angular/router": "^5.0.1",
    "@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.5",
    "@ngrx/store": "^4.1.1",
    "bootstrap": "^4.0.0-beta.2",
    "core-js": "^2.4.1",
    "firebase": "^4.6.1",
    "font-awesome": "^4.7.0",
    "rxjs": "^5.5.2",
    "zone.js": "^0.8.14"
  },
  "devDependencies": {
    "@angular/cli": "^1.5.0",
    "@angular/compiler-cli": "^5.0.1",
    "@angular/language-service": "^5.0.1",
    "@types/jasmine": "~2.5.53",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "~3.2.0",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.2.0",
    "tslint": "~5.7.0",
    "typescript": "^2.4.2"
  }
}

AppModule.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { StoreModule } from '@ngrx/store/src/store_module';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './core/header/header.component';
import { FullBodyComponent } from './core/full-body/full-body.component';
import { FooterComponent } from './core/footer/footer.component';
import { ExploreComponent } from './core/full-body/explore/explore.component';
import { ContactComponent } from './core/full-body/contact/contact.component';
import { HomeComponent } from './core/home/home.component';

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    FullBodyComponent,
    FooterComponent,
    ExploreComponent,
    ContactComponent,
    HomeComponent
  ],
  imports: [
    HttpClientModule,
    BrowserModule,
    CommonModule,
    NgbModule.forRoot(),
    AppRoutingModule,
    StoreModule.forRoot({})
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

SpacesModule.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { StoreModule } from '@ngrx/store';

import { SpacesWelcomeComponent } from './spaces-welcome/spaces-welcome.component';
import { SpaceEditComponent } from './space-edit/space-edit.component';
import { SpacesListComponent } from './spaces-list/spaces-list.component';
import { SpaceDetailComponent } from './space-detail/space-detail.component';
import { SpacesComponent } from './spaces.component';
import { SpacesRoutingModule } from './spaces-routing.module';
import { SpaceItemComponent } from '../spaces/spaces-list/space-item/space-item.component';
import { spacesReducers } from './store/spaces.reducers';

@NgModule({
  imports: [
    FormsModule,
    CommonModule,
    SpacesRoutingModule,
    StoreModule.forFeature('spaces', spacesReducers)
  ],
  declarations: [
    SpacesComponent,
    SpaceDetailComponent,
    SpacesListComponent,
    SpaceEditComponent,
    SpacesWelcomeComponent,
    SpaceItemComponent
  ]
})

export class SpacesModule {}

SpacesReducers.ts

import * as SpacesActions from './spaces.actions';

import { Space } from '../../shared/space.model';

export interface FeatureState {
  spaces: State;
}

export interface State {
  spaces: Space[];
}

const initialState: State = {
  spaces: [
    new Space('Churrasqueira', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
    new Space('Churrasqueira2', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
    new Space('Churrasqueira3', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
    new Space('Churrasqueira3', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
    new Space('Churrasqueira3', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
    new Space('Churrasqueira3', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
    new Space('Churrasqueira4', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg')
  ]
};

export function spacesReducers(state = initialState, action: SpacesActions.SpacesActions) {
  switch (action.type) {
    case SpacesActions.ADD_SPACE:
      return {
        ...state,
          spaces: [...state.spaces, action.payload]
      };
    case SpacesActions.UPDATE_SPACE:
      const space = state.spaces[action.payload.index];
      const updatedRecipe = {
        ...space,
        ...action.payload.updatedSpace
      };
      const spaces = [...state.spaces];
      spaces[action.payload.index] = updatedRecipe;
      return {
        ...state,
          spaces: spaces
      };
    case SpacesActions.DELETE_SPACE:
      const deletedSpaces = [state.spaces];
      deletedSpaces.splice(action.payload, 1);
      return {
        ...state,
          spaces: deletedSpaces
      };
      default:
        return state;
  }
}

SpacesActions.ts

import { Action } from '@ngrx/store';

import { Space } from '../../shared/space.model';

export const ADD_SPACE = 'ADD_SPACE';
export const UPDATE_SPACE = 'UPDATE_SPACE';
export const DELETE_SPACE = 'DELETE_SPACE';

export class AddSpace implements Action {
  readonly type = ADD_SPACE;

  constructor(public payload: Space) {}
}

export class UpdateSpace implements Action {
  readonly type = UPDATE_SPACE;

  constructor(public payload: {index: number, updatedSpace: Space}) {}
}

export class DeleteSpace implements Action {
  readonly type = DELETE_SPACE;

  constructor(public payload: number) {}
}

export type SpacesActions = AddSpace | UpdateSpace | DeleteSpace;

SpacesList.component.ts

import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { Store } from '@ngrx/store';
import { Subscription } from 'rxjs/Subscription';
import { Observable } from 'rxjs/Observable';

import { Space } from './../../shared/space.model';
import { SpacesService } from '../spaces.service';
import * as fromSpaces from '../store/spaces.reducers';

@Component({
  selector: 'app-spaces-list',
  templateUrl: './spaces-list.component.html',
  styleUrls: ['./spaces-list.component.scss']
})

export class SpacesListComponent implements OnInit, OnDestroy {
  spacesState: Observable<fromSpaces.State>;
  // spaces: Space[];

  private addMode = false;

  subscription: Subscription;

  constructor(private spacesService: SpacesService,
              private store: Store<fromSpaces.FeatureState>
            ) { }

  ngOnInit() {
    this.spacesState = this.store.select('spaces');

    this.subscription = this.spacesService.addModeActivated
    .subscribe(
      (addMode: boolean) => {
        this.addMode = addMode;
      }
    );

  //   this.subscription = this.spacesService.spacesChanged
  //   .subscribe(
  //     (spaces: Space[]) => {
  //       this.spaces = spaces;
  //     }
  //   );
  // this.spaces = this.spacesService.getSpaces();
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

  enableAddMode() {
    // this.addMode = true;
    this.spacesService.addModeActivated.next(true);
  }
}

After digging over the internet I figured out the answer. My problem was related to wrong file importation.

In my app.module, instead of importing the StoreModule from @ngrx/store I was importing from @ngrx/store/src/store_module . It happened due to the AutoImport of Visual Code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM