Ionic-cli: super starter + generators : TypeError: Cannot read property 'length' of undefined

Created on 2 Jun 2017  路  11Comments  路  Source: ionic-team/ionic-cli

_From @martineca on June 2, 2017 9:46_

Type: bug

Ionic Version: 2.x

Platform: all

To reproduce the bug simply do 'ionic start sampleApp' then choose super as option. After installation is complete try creating a service with 'ionic g provider sampleService' and you will get error: cannot read property of 'length' of undefined.

_Copied from original issue: ionic-team/ionic#11898_

bug

Most helpful comment

@martineca No, it's a bug.

For a workaround, move the array returned by the silly providers() function into the @NgModule decorator.

In other words, replace

providers: providers()

with

providers: [
    Api,
    Items,
    User,
    Camera,
    GoogleMaps,
    SplashScreen,
    StatusBar,

    { provide: Settings, useFactory: provideSettings, deps: [Storage] },
    // Keep this to enable Ionic's runtime error handling during development
    { provide: ErrorHandler, useClass: IonicErrorHandler }
  ]

All 11 comments

_From @AmitMY on June 2, 2017 10:38_

What version CLI are you using? Please add the output of ionic info

_From @martineca on June 2, 2017 11:0_

global packages:

@ionic/cli-utils : 1.2.0
Ionic CLI        : 3.2.0

local packages:

@ionic/app-scripts              : 1.3.7
@ionic/cli-plugin-ionic-angular : 1.3.0
Ionic Framework                 : ionic-angular 3.3.0

System:

Node       : v6.10.3
OS         : Windows 7
Xcode      : not installed
ios-deploy : not installed
ios-sim    : not installed

_From @AmitMY on June 2, 2017 11:3_

Thanks, so it seems like the issue should be moved to ionic-cli. @jgw96 can you please move it?

Yuuup. App-scripts can't append the NgModule definition for the super starter because it uses a different format for app.module.ts

[DEBUG] TypeError: Cannot read property 'length' of undefined
            at Object.appendNgModuleDeclaration (/Users/dan/ionic/wowsuper/node_modules/@ionic/app-scripts/dist/util/typescript-utils.js:213:25)
            at /Users/dan/ionic/wowsuper/node_modules/@ionic/app-scripts/dist/generators/util.js:163:46

app.module.ts:

export function providers() {
  return [
    Api,
    Items,
    User,
    Camera,
    GoogleMaps,
    SplashScreen,
    StatusBar,

    { provide: Settings, useFactory: provideSettings, deps: [Storage] },
    // Keep this to enable Ionic's runtime error handling during development
    { provide: ErrorHandler, useClass: IonicErrorHandler }
  ];
}
  providers: providers()

we expect that object key ^ to be an array

Thanks for replying. Could you give me an example similar to 'ionic g provider sampleService' that would work with the super starter?

@martineca No, it's a bug.

For a workaround, move the array returned by the silly providers() function into the @NgModule decorator.

In other words, replace

providers: providers()

with

providers: [
    Api,
    Items,
    User,
    Camera,
    GoogleMaps,
    SplashScreen,
    StatusBar,

    { provide: Settings, useFactory: provideSettings, deps: [Storage] },
    // Keep this to enable Ionic's runtime error handling during development
    { provide: ErrorHandler, useClass: IonicErrorHandler }
  ]

@dweib nice, it fixed the issue.
For those of you who use the function providers() to switch between mocks and real-cordova-plugins for example, you can use multi providers instead to programmatically use the class you need.

https://angular.io/docs/ts/latest/api/core/index/ValueProvider-interface.html:
https://blog.thoughtram.io/angular2/2015/11/23/multi-providers-in-angular-2.html

Same issue, fixed by the replace stated by @dwieeb

@bleuscyther could you give a quick example on how to use multiproviders to accomplish this? I'm finding the docs slightly opaque on the topic.

I use a different approach now for the mock:

\* app.module.ts*\
...
// Mocks
import {CameraMock} from "../mocks/camera";
...

const USE_MOKS = false; // should not be in a config file , doesn't work well with  `build --prod`
....
@NgModule({
    ...
     providers: [
        {provide: Camera, useClass: USE_MOKS ? CameraMock : Camera},
         ...
    ]
})
export class AppModule {
}
````
And here is an example of mock:
``` typeScript
import {Camera} from "@ionic-native/camera";

export class CameraMock extends Camera {
    getPicture(options) {
        console.warn('Camera - Using mocks - getPicture');

        return new Promise((resolve, reject) => {
            let fakeImage = '<yourImageDataURL>`
           resolve(fakeImage);
        })
    }
}

This is fixed in latest super starter.

Was this page helpful?
0 / 5 - 0 ratings