hsuanxyz / ionic-stepper

Steppers components for Ionic / ionic2
https://hsuanxyz.github.io/demo/ionic-stepper/
MIT License
51 stars 39 forks source link

NullInjectorError: No provider for IonicStepperComponent! #2

Closed Nightbr closed 6 years ago

Nightbr commented 6 years ago

Hey,

I have an error when I tried to use ion-stepper in an ionic modal lazy loaded.

modal.module.ts

import { NgModule } from '@angular/core';
import { IonicPageModule, IonicModule } from 'ionic-angular';
import { TranslateModule } from '@ngx-translate/core';
import { ModalPage } from './modal.page';
import IonicStepperModule from 'ionic-stepper';

@NgModule({
    declarations: [
        ModalPage
    ],
    imports: [
        IonicModule,
        IonicStepperModule,
        IonicPageModule.forChild(ModalPage),
        TranslateModule,
    ],
    entryComponents: [
        ModalPage
    ]
})
export class ModalPageModule { }
import { Component } from '@angular/core';
import { NavController, ViewController, IonicPage, App, NavParams } from 'ionic-angular';

@IonicPage({
    name: 'ModalPage',
})
@Component({
    selector: 'page-modal-component',
    templateUrl: 'modal.page.html'
})
export class ModalPage {

    form: any;

    constructor(public navCtrl: NavController,
        public viewCtrl: ViewController,
        params: NavParams) {

        this.form = params.get('form');
        console.log(this.form);
    }

    selectChange(e) {
        console.log(e);
    }

    dismiss() {
        this.viewCtrl.dismiss();
    }

}

In another page component to open the modalPage:

    startForm() {
        let myModal = this.modalCtrl.create('ModalPage', { 'form': this.component });
        myModal.present();
    }

I also add in app.module.ts import IonicStepperModule from 'ionic-stepper'; and

imports: [
    BrowserModule,
    BrowserAnimationsModule,
    IonicStepperModule,
IonicModule.forRoot(MyApp),
...

But when I opened the modal:

Uncaught (in promise): Error: StaticInjectorError[IonicStepperComponent]: \n StaticInjectorError[IonicStepperComponent]: \n NullInjectorError: No provider for IonicStepperComponent!\n_NullInjector.prototype.get@http://localhost:8100/build/vendor.js:1588:19\nresolveToken@http://localhost:8100/build/vendor.js:1876:17\ntryResolveToken@http://localhost:8100/build/vendor.js:1818:16\nStaticInjector.prototype.get@http://localhost:8100/build/vendor.js:1689:20\nresolveToken@http://localhost:8100/build/vendor.js:1876:17\ntryResolveToken@http://localhost:8100/build/vendor.js:1818:16\nStaticInjector.prototype.get@http://localhost:8100/build/vendor.js:1689:20\nresolveNgModuleDep@http://localhost:8100/build/vendor.js:11250:12\nNgModuleRef_.prototype.get@http://localhost:8100/build/vendor.js:12471:16\nresolveNgModuleDep@http://localhost:8100/build/vendor.js:11250:12\nNgModuleRef_.prototype.get@http://localhost:8100/build/vendor.js:12471:16\nresolveDep@http://localhost:8100/build/vendor.js:12967:12\ncreateClass@http://localhost:8100/build/vendor.js:12829:29\ncreateDirectiveInstance@http://localhost:8100/build/vendor.js:12676:37\ncreateViewNodes@http://localhost:8100/build/vendor.js:14114:53\ncallViewAction@http://localhost:8100/build/vendor.js:14546:13\nexecComponentViewsAction@http://localhost:8100/build/vendor.js:14455:13\ncreateViewNodes@http://localhost:8100/build/vendor.js:14142:5\ncreateRootView@http://localhost:8100/build/vendor.js:14004:5\ncallWithDebugContext@http://localhost:8100/build/vendor.js:15405:39\ndebugCreateRootView@http://localhost:8100/build/vendor.js:14706:12\nComponentFactory_.prototype.create@http://localhost:8100/build/vendor.js:11625:37\nComponentFactoryBoundToModule.prototype.create@http://localhost:8100/build/vendor.js:4587:16\nViewContainerRef_.prototype.createComponent@http://localhost:8100/build/vendor.js:11822:45\nModalCmp.prototype.ionViewPreLoad@http://localhost:8100/build/vendor.js:60281:28\nViewController.prototype._lifecycle@http://localhost:8100/build/vendor.js:19798:13\nViewController.prototype._preLoad@http://localhost:8100/build/vendor.js:19660:9\nNavControllerBase.prototype._preLoad@http://localhost:8100/build/vendor.js:53528:9\nNavControllerBase.prototype._viewInit@http://localhost:8100/build/vendor.js:53218:9\nNavControllerBase.prototype._nextTrns/<@http://localhost:8100/build/vendor.js:53029:17\nF</l</t.prototype.invoke@http://localhost:8100/build/polyfills.js:3:14974\nonInvoke@http://localhost:8100/build/vendor.js:5294:24\nF</l</t.prototype.invoke@http://localhost:8100/build/polyfills.js:3:14901\nF</c</r.prototype.run@http://localhost:8100/build/polyfills.js:3:10124\nf/<@http://localhost:8100/build/polyfills.js:3:20240\nF</l</t.prototype.invokeTask@http://localhost:8100/build/polyfills.js:3:15649\nonInvokeTask@http://localhost:8100/build/vendor.js:5285:24\nF</l</t.prototype.invokeTask@http://localhost:8100/build/polyfills.js:3:15562\nF</c</r.prototype.runTask@http://localhost:8100/build/polyfills.js:3:10815\no@http://localhost:8100/build/polyfills.js:3:7887\nF</h</e.invokeTask@http://localhost:8100/build/polyfills.js:3:16823\np@http://localhost:8100/build/polyfills.js:2:27646\nv@http://localhost:8100/build/polyfills.js:2:27893\n

Any idea?

Thanks for your help.

add:

$ ionic info

cli packages: (/home/nightbringer/.nvm/versions/node/v6.9.5/lib/node_modules)

    @ionic/cli-utils  : 1.19.1
    ionic (Ionic CLI) : 3.19.1

global packages:

    cordova (Cordova CLI) : 8.0.0

local packages:

    @ionic/app-scripts : 3.1.8
    Cordova Platforms  : android 7.0.0
    Ionic Framework    : ionic-angular 3.9.2

System:

    Android SDK Tools : 26.1.1
    Node              : v6.9.5
    npm               : 3.10.10
    OS                : Linux 4.13

Environment Variables:

    ANDROID_HOME : /home/nightbringer/sdk/android-sdk-linux/

Misc:

    backend : pro
Nightbr commented 6 years ago

I found why it was not working...

In my template, I tried to put ionicStepperPrevious and ionicStepperNext outside ion-step...

modal.page.html


<ion-header>

  <ion-navbar>
    <ion-buttons start>
      <button ion-button (click)="dismiss()">Close</button>
    </ion-buttons>
    <ion-title>Modals</ion-title>
  </ion-navbar>

</ion-header>

<ion-content padding>
  <ion-stepper #stepper (selectIndexChange)="selectChange($event)">
    <ion-step label="Intro">
      {{ form.intro }}

    </ion-step>
    <ion-step *ngFor="let field of form.fields" [label]="field.label" [description]="field.description">
      {{ field | json }}

    </ion-step>
    <ion-step label="Outro">
      {{ form.outro }}

    </ion-step>
  </ion-stepper>

</ion-content>

<ion-footer>
  <ion-toolbar>
    <ion-title>Footer</ion-title>
    <ion-buttons end>
      <button ion-button color="light" small ionicStepperPrevious>Previous</button>
      <button ion-button ionicStepperNext>Next</button>
    </ion-buttons>
  </ion-toolbar>
</ion-footer>
Nightbr commented 6 years ago

I finally get it to work with viewChild:

import { Component, ViewChild, ElementRef } from '@angular/core';
import { NavController, ViewController, IonicPage, App, NavParams } from 'ionic-angular';
import { IonicStepperComponent } from 'ionic-stepper';

@IonicPage({
    name: 'FormPage',
})
@Component({
    selector: 'page-form-component',
    templateUrl: 'form.page.html'
})
export class FormPage {

    @ViewChild('stepper') stepper: IonicStepperComponent;
    form: any;

    constructor(public navCtrl: NavController,
        public viewCtrl: ViewController,
        params: NavParams) {

        this.form = params.get('form');
        console.log(this.form);
    }

    next() {
        this.stepper.nextStep();
    }

    previous() {
        this.stepper.previousStep();
    }

    selectChange(e) {
        console.log(e);
    }

    dismiss() {
        this.viewCtrl.dismiss();
    }

}

<ion-header>

  <ion-navbar>
    <ion-buttons start>
      <button ion-button (click)="dismiss()">Close</button>
    </ion-buttons>
    <ion-title>Modals</ion-title>
  </ion-navbar>

</ion-header>

<ion-content padding>
  <ion-stepper #stepper (selectIndexChange)="selectChange($event)">
    <ion-step label="Intro">
      {{ form.intro }}

    </ion-step>
    <ion-step *ngFor="let field of form.fields" [label]="field.label" [description]="field.description">
      {{ field | json }}

    </ion-step>
    <ion-step label="Outro">
      {{ form.outro }}

    </ion-step>
  </ion-stepper>

</ion-content>

<ion-footer>
  <ion-toolbar>
    <ion-title>Footer</ion-title>
    <ion-buttons end>
      <button ion-button (click)="previous()">Previous</button>
      <button ion-button (click)="next()">Next</button>
    </ion-buttons>
  </ion-toolbar>
</ion-footer>

stepper