Platform: Error: Cannot convert undefined or null to object

Created on 8 Aug 2017  路  20Comments  路  Source: ngrx/platform

I'm submitting a...


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

What is the current behavior?


With AOT build Error Cannot convert undefined or null to object is thrown at this line
https://github.com/ngrx/platform/blob/48a2381c212d5dd3fa2b9435776c1aaa60734235/modules/store/src/utils.ts#L16
because reducers is null.

  const reducerKeys = Object.keys(reducers);

Expected behavior:


I'm injecting reducers as described here
https://github.com/ngrx/platform/blob/master/docs/store/api.md#injecting-reducers

Minimal reproduction of the problem with instructions:


https://github.com/ValeryVS/angular-storage-experiment/blob/02fd926e17547abfdb213b3d8dd3af3392218238/src/app/store/reducer.ts
Same error has been reproduced there.
I can update repo to match instruction above.

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

$ node -v
v6.11.1
$ npm -v
3.10.10

@ngrx/[email protected]

Other information:

Most helpful comment

I am getting the same error and I'm not sure if it's a problem of ngrx or if it's fixed yet.

I tried using https://github.com/ngrx/platform/pull/254 fix but it doesn't seem to work.

It works perfectly fine if I build the application using JIT strategy.

It fails when I use AOT strategy using ng build --aot --watch --extract-css false --output-hashing none command.

I tried to debug the problem and found that combineReducers function in store.es5.js gets fired twice (unlike in JIT where it gets fired only once) which I didn't understand.
The reducers parameter of this function is null in second call and hence it throws the error.

I have got a couple of screenshots for further details.

Console Error

aot-error-console-error

store.es5.js file

aot-error-store es5 js

Please let me know if I am missing something. Thanks.

All 20 comments

Possible relative #175

I have the same issue. I am on Typescript 2.4.2. Disabling AOT fixes the issue. My getReducers function is not executed (I added a console.log).

Right, I also tried to debug this a while, and found that reducers factory is not executed.

Wouldn't that mean it is more a CLI issue though? AOT is only active in production mode right? Because everything works as expected in development mode.

@Christian24
Well... it can be issue with ngrx/store or documentation or with angular itself. Don't think that CLI is relative here.
You can ng build --prod --aot=false to make production build without though.

@ValeryVS true. I have tried that. When disabling AOT it works, but I would hate to give up AOT.

I have a fix for this that will work for JiT/AoT. It should land soon once I submit the PR

While the error goes away, my reducer still is not called. I detailed this in #189

@ValeryVS @Christian24 @brandonroberts
I have the same issue.

It works on the first load (empty cache and hard reload), but after that when doing a normal reload, it get: Uncaught TypeError: Cannot convert undefined or null to object at Function.keys ()

I tried various approaches like #189 but non of them worked.

Were you able to solve it? And if yes, how?

I am getting the same error and I'm not sure if it's a problem of ngrx or if it's fixed yet.

I tried using https://github.com/ngrx/platform/pull/254 fix but it doesn't seem to work.

It works perfectly fine if I build the application using JIT strategy.

It fails when I use AOT strategy using ng build --aot --watch --extract-css false --output-hashing none command.

I tried to debug the problem and found that combineReducers function in store.es5.js gets fired twice (unlike in JIT where it gets fired only once) which I didn't understand.
The reducers parameter of this function is null in second call and hence it throws the error.

I have got a couple of screenshots for further details.

Console Error

aot-error-console-error

store.es5.js file

aot-error-store es5 js

Please let me know if I am missing something. Thanks.

Any updates on this? I've encountered the same error ...

I had the same issue.
I was able to solve it by declaring the getReducers function in my feature module's module.ts file, instead of declaring it in the reducer's index.ts file.

FYI the problem was, that angular AOT does not work with default exports (at least for reducers).
I fixed my problem by refactoring all reducer default exports to named exports.

@David-Mueller , can you show an example of this please?

export default function (....) { 
  ...
}

becomes

export function reducer (...) {
 ...
}

Well I don't have export default function anywhere in my code. I am using my own Angular 6 library in my app. Everything compiles and runs with ng serve. When I build for production it compiles but when I try and run it locally I get the error mentioned above. I tried with --aot=true and --aot=false

Hi,
unfortunately, this fixed it for me.

I'd double check, if all of the reducer imports are fine or if I pass undefined as a reducer somewhere with aot enabled.
Good luck

I have struggled with the same issue. I managed to solve it by declaring a wrapper for the reducer function right inside the module.ts file, similar to @kristof01 's suggestion above.

Original failing code

@NgModule({
  imports: [
    StoreModule.forFeature(
      'feature', featureNs.reducers 
    ),     ...
  ],`

( featureNs is a namespace and reducers is an ActionReducerMap.) Works with a JIT build, not an AOT build.

I got the AOT build working with (all in the module.ts file):

const combinedReducer: ActionReducer<featureNs.state, Action> =
   combineReducers(featureNs.reducers);

export function reducerWrapper(
  state: featureNs.state, action: Action): featureNs.state {
  return combinedReducer(state, action);
}

@NgModule({
  imports: [
    StoreModule.forFeature(
      'feature', reducerWrapper 
    ),     ...
  ],`

Note: the above module was part of an Angular feature Library (build with ng-packagr), and then imported in an app build with the AOT compiler. Not sure if the library part makes any difference...

Things were working perfectly in DEV mode, then it became a nightmare when I deployed my application to production with the AOT flag on. It took me 2 days to figure out the solution for my specific case.

So I was using Object.assign to combine all my reducers.

Before
export const AppReducers = Object.assign({ APP_REDUCER: AppReducer }, OtherReducers );

After
export const AppReducers = { APP_REDUCER: AppReducer, ...OtherReducers } );

After a lot of hit and trial, I just removed the Object.assign and used spread operator, tadda, everything is working fine with and without the AOT flag. Surprising.

But I really want to understand why Object.assign wasted my 2 days? if anyone can put some lights on it?

@mcoomans Thanks for your comment. I was facing the same issue and without your comment I wouldn't be able to solve it. Your way in the comment fixes it but there is also a different way.

Doing it like the 2nd snippet here fixes it too. (https://github.com/ngrx/platform/blob/v5.2.0/docs/store/api.md#injecting-reducers)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mappedinn picture mappedinn  路  3Comments

itprodavets picture itprodavets  路  3Comments

hccampos picture hccampos  路  3Comments

dollyshah-02-zz picture dollyshah-02-zz  路  3Comments

gperdomor picture gperdomor  路  3Comments