Platform: store-devtools: cannot read property 'state' of undefined

Created on 3 Dec 2017  路  27Comments  路  Source: ngrx/platform

I'm submitting a...


[ x ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Feature request
[ ] Documentation issue or request

What is the current behavior?

After syncing the latest ngrx into Google I have one of the tests failing (it's bootstrapping entire AppModule and has StoreDevtoolsModule.instrument({maxAge: 25}) as part of imports). The test fails to initialize, so none of the actual test code is executed yet.

The issue is surfaced in unliftState when computedStates has length of 2, yet currentStateIndex is 2 as well, and thus computedStates[currentStateIndex] returns undefiend.

screen shot 2017-12-02 at 8 59 06 pm

This is what was the state leading up to this call:

screen shot 2017-12-02 at 8 56 36 pm

Expected behavior:

Minimal reproduction of the problem with instructions:

Version of affected browser(s),operating system(s), npm, node and ngrx:

Other information:

Needs Reproduction Store Devtools bug

Most helpful comment

I had the same issue here. Fixed it by changing the import sequence (import feature module after store and store devools module)

Before (with Error):

app.module.ts
----------------
...
imports: [
    BrowserModule,
    FeatureModule, // feature module was imported early
    StoreModule.forRoot({}),
    EffectsModule.forRoot([]),
    StoreDevtoolsModule.instrument({maxAge: 25})
  ]
...
----------------
feature.module.ts
----------------
...
 imports: [
    CommonModule,
    StoreModule.forFeature('feature', featureReducerToken),
    EffectsModule.forFeature([FeatureEffects])
  ],
...

After (solved)

app.module.ts
----------------
...
imports: [
    BrowserModule,
    StoreModule.forRoot({}),
    EffectsModule.forRoot([]),
    StoreDevtoolsModule.instrument({maxAge: 25}),
    FeatureModule // import feature module after StoreModule and StoreDevtoolsModule
  ]
...
----------------
feature.module.ts
----------------
...
 imports: [
    CommonModule,
    StoreModule.forFeature('feature', featureReducerToken),
    EffectsModule.forFeature([FeatureEffects])
  ],
...

All 27 comments

@alex-okrushko we are looking into this issue. Is there a certain sequence of events you can reproduce that triggers this issue?

Not 100% certain, but it appears that StoreDevtoolsModule.instrument({maxAge: 25}) was being imported twice.
@benlesh might have more details (that's his project that's causing troubles :) )

With one StoreDevtoolsModule everything works.
@brandonroberts do you want it closed? That's a weird case but for some reason it was working before.

@alex-okrushko Yes. How was the second StoreDevtoolsModule introduced? Through another module imported lazily? We could add a guard to prevent it from being loaded more than once, but I'd like to understand how it came in first.

In the same NgModule through unusual way:

// foo.ts
export const REQUIRED_MODULES = [
   StoreModule.forRoot({}),
   EffectsModule.forRoot([]),
   StoreDevtoolsModule.instrument({maxAge: 25}),
];

// app_module.ts
import {REQUIRED_MODULES} from './foo.ts';

@NgModule({
  declarations: [  ],
  imports: [
    ...REQUIRED_MODULES,
    BrowserAnimationsModule,
    HttpModule,
    StoreDevtoolsModule.instrument({maxAge: 25}),
  ],
})
export class AppModule {}

I'm having this problem. StoreDevtoolsModule is only being imported once.

@ccpony provide a repo with a reproduction of this issue

For our part, it was only being provided once as well.

Yes, I'll prepare a repo. However, what I can tell you now is that the error is triggered on the following line of code:

export const getSupplierState = createFeatureSelector<SupplierState>('suppliers');

...which produced the "cannot read property 'suppliers' of undefined" in the browser.

@benlesh It was provided twice. I removed the second installation.

@ccpony
You are having the different issue - not the one that was originally reported. You might want to open the separate issue for it.

Thank you. I opened a new issue.

I eliminated "cannot read property 'state' of undefined" error by changing import sequence in app.module.ts.
Take a good look at my app.module.ts and try to change your import sequence accordingly.
I'm using ngrx 5.0.0.

imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
StoreModule.forRoot(reducers, { metaReducers }),
StoreRouterConnectingModule,
RouterModule.forRoot(routes, {
useHash: false
}),
StoreDevtoolsModule.instrument({
name: 'NgRx Store DevTools',
logOnly: environment.production,
}),
NgbModule.forRoot(),
JwtModule.forRoot({
jwtOptionsProvider: {
provide: JWT_OPTIONS,
useFactory: jwtOptionsFactory,
deps: [TokenService]
}
}),
AuthModule.forRoot(), // critical!! application crash if AuthModule (with effects) is below EffectsModule
EffectsModule.forRoot(effects)
],

I had the same issue here. Fixed it by changing the import sequence (import feature module after store and store devools module)

Before (with Error):

app.module.ts
----------------
...
imports: [
    BrowserModule,
    FeatureModule, // feature module was imported early
    StoreModule.forRoot({}),
    EffectsModule.forRoot([]),
    StoreDevtoolsModule.instrument({maxAge: 25})
  ]
...
----------------
feature.module.ts
----------------
...
 imports: [
    CommonModule,
    StoreModule.forFeature('feature', featureReducerToken),
    EffectsModule.forFeature([FeatureEffects])
  ],
...

After (solved)

app.module.ts
----------------
...
imports: [
    BrowserModule,
    StoreModule.forRoot({}),
    EffectsModule.forRoot([]),
    StoreDevtoolsModule.instrument({maxAge: 25}),
    FeatureModule // import feature module after StoreModule and StoreDevtoolsModule
  ]
...
----------------
feature.module.ts
----------------
...
 imports: [
    CommonModule,
    StoreModule.forFeature('feature', featureReducerToken),
    EffectsModule.forFeature([FeatureEffects])
  ],
...

Workaround didn't work for me. I downgraded to 4.x for now. All great with 4.

Downgrade to 4.1.1 also worked for me. 5.0.0 produces an error.

Here is a branch to reproduce/inspect the error:
https://github.com/angularjs-de/angular-advanced-workshop/tree/issue-report-store-devtools

I tried @dfreier 's idea, no luck. I changed all my modules and the app module to import the store first, but i'm still getting the error cannot read property 'state' of undefined. I have async routing, and I select from my store like this:
export const selectNetwork = createFeatureSelector<NetworkState>('network'); export const selectNetworkDns = createSelector(selectNetwork, (state) => state.dns);

then in my feature component, I select from the store with this method imported:

// called in ngOnInit
getDns() {
        // reach out to ngrx store
        this.dnsServers$ = this.store.select(selectNetworkDns);
        this.store.dispatch(new NetworkActions.GetIpList());
}

and in my html I have the async pipe and the safe operator:
*ngFor="let server of (dnsServers$ | async)?.dns; let index = index trackBy: trackByIndex"

Downgraded to Angular 4 and everything works great :/

maybe I did not import in the correctly suggested order?
app.module:

    BrowserModule,
    StoreModule.forRoot({}),
    AppRoutingModule,
    OverviewModule,
    ReactiveFormsModule,
    FormsModule,
    BrowserAnimationsModule,
    AngularFontAwesomeModule,
    HttpClientModule,
    SimpleNotificationsModule.forRoot(),
    !environment.production ? StoreDevtoolsModule.instrument() : []

feature module:

        CommonModule,
        StoreModule.forFeature('network', {
            dns: networkReducers.dnsReducer,
            wan: networkReducers.wanReducer,
            lan: networkReducers.lanReducer,
            obm: networkReducers.ObmReducer,
            staticFirewall: networkReducers.staticFirewallReducer,
            dhcp: networkReducers.dhcpReducer
        }),
        NetworkRoutingModule,
        EffectsModule.forRoot([NetworkEffects]),
        FormsModule,
        ReactiveFormsModule,
        SharedModule

I was having the same issue after upgrading my ngrx modules to 5.0.0, and @dfreier 's solution worked for me

Some feedback please: I've experienced "cannot read property 'x' of undefined" and the problem is the I don't know how to debug it. Ultimately, if I'm able to find the problem, it's largely by trial and error. Proceeding with ngrx and angular 5 is daunting for me because reactive programming seems to be very difficult to debug. How do you all deal with that issue (other than peppering your code with .do functions)?

Here is a very simple reproduction: https://stackblitz.com/edit/ngrx-624-repro?file=app/app.module.ts
Working:

  StoreModule.forRoot({ count: counterReducer }),
  StoreDevtoolsModule.instrument({ maxAge: 25, }),

Not working:

  StoreModule.forRoot({ }),
  CounterModule,
  StoreDevtoolsModule.instrument({ maxAge: 25, }),

Still not working with @dfreier's proposal:

  StoreModule.forRoot({ }),
  StoreDevtoolsModule.instrument({ maxAge: 25, }),
  CounterModule,

hmmm. I'm still getting this issue after getting the latest

@CHBaker unless you're running nightlies this fix has not been released yet

@brandonroberts Oh, alright. When is the release date? Also, is nightlies just a version of NgRx updated nightly?

Soon. Nightlies are updated whenever we merge into master

Is it expected that 5.1 fixes this? It does not appear to be the case for me. I get the state is undefined error as seen in #777 (marked duplicate of this). Workarounds above do not help me. store 4.1.1 worked fine.

Actually I was able to work around by rearranging my module imports. I had a service that referenced a selector. Moving that service module above the reducers/effects module fixed it. Should the ordering of module imports actually matter?

@bufke yes, upgrading to 5.1 should fix the issue. Ordering of imports does matter when mixing NgModule and ModuleWithProviders. The latest release makes the order of dependencies more explicit.

Was this page helpful?
0 / 5 - 0 ratings