Trying to use a component in two pages with lazy loading

Hello, I get stuck in a simple (I guess) problem, trying use a component in two pages with lazy loading and I don’t know what’s the problem, I research in stackoverflow, google and Ionic Forum and don’t find something like this, sorry about so many files, here is my all data (erros, modules, component, html, ts):

Ionic info

cli packages: (/usr/local/lib/node_modules)

    @ionic/cli-utils  : 1.9.2
    ionic (Ionic CLI) : 3.9.2

global packages:

    Cordova CLI : 7.0.1 

local packages:

    @ionic/app-scripts : 2.1.4
    Cordova Platforms  : android 6.2.3 ios 4.4.0
    Ionic Framework    : ionic-angular 3.6.0

System:

    ios-deploy : 1.9.1 
    ios-sim    : 6.0.0 
    Node       : v6.9.5
    npm        : 3.10.10 
    OS         : macOS Sierra
    Xcode      : Xcode 8.2.1 Build version 8C1002

Error

components/formulario-usuario/formulario-usuario

import { Component, Input } from '@angular/core';
import { App, IonicPage, NavController, NavParams, LoadingController } from 'ionic-angular';

// PROVIDERS
import { AuthProvider } from '../../providers/auth/auth';
import { AuxiliarProvider } from '../../providers/auxiliar/auxiliar';
import { UsuarioProvider } from '../../providers/usuario/usuario';

// PAGES
import { HomePage } from '../../pages/home/home';

@Component({
  selector: 'formulario-usuario',
  templateUrl: 'formulario-usuario.html'
})
export class FormularioUsuarioComponent {
...

components/components.module.ts

import { NgModule } from '@angular/core';
import {IonicModule}  from 'ionic-angular'
import { FormularioUsuarioComponent } from './formulario-usuario/formulario-usuario';
@NgModule({
	declarations: [FormularioUsuarioComponent],
	imports: [IonicModule],
	exports: [FormularioUsuarioComponent]
})
export class ComponentsModule {}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { LOCALE_ID, ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { HttpModule } from '@angular/http';
import { AngularFireModule } from 'angularfire2';
import { AngularFireDatabaseModule } from 'angularfire2/database';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { TextMaskModule } from 'angular2-text-mask';
// import { AngularFireDatabaseModule } from 'angularfire2/database';
// import { AngularFireAuthModule } from 'angularfire2/auth';

// NATIVE IMPORTS
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';
import { Facebook } from '@ionic-native/facebook'
import { GooglePlus } from '@ionic-native/google-plus';
import { IonicStorageModule, Storage } from '@ionic/storage';
import { Geolocation } from '@ionic-native/geolocation';

// PAGE IMPORTS
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { InicioPage } from '../pages/inicio/inicio';
import { LoginPage } from '../pages/login/login';
import { RegistrarPage } from '../pages/registrar/registrar';
import { EsqueciSenhaPage } from '../pages/esqueci-senha/esqueci-senha';
import { CrudUsuarioPage } from '../pages/crud-usuario/crud-usuario';

// COMPONENT IMPORTS
// import { FormularioUsuarioComponent } from '../components/formulario-usuario/formulario-usuario';

// PROVIDERS IMPORTS
import { AuthProvider } from '../providers/auth/auth';
import { AuxiliarProvider } from '../providers/auxiliar/auxiliar';
import { UsuarioProvider } from '../providers/usuario/usuario';


export const firebaseConfig = {
  apiKey: "xxx",
  authDomain: "xxx",
  databaseURL: xxx,
  projectId: "xxx",
  storageBucket: "xxx",
  messagingSenderId: "xxx"
}


@NgModule({
  declarations: [
    MyApp,
    HomePage,
    InicioPage,
    LoginPage,
    RegistrarPage,
    EsqueciSenhaPage,
    CrudUsuarioPage
    // FormularioUsuarioComponent
  ],
  imports: [
    HttpModule,
    BrowserModule,
    IonicModule.forRoot(MyApp, {
      backButtonText: ''
      // pageTransition: 'ios'
    }),
    IonicStorageModule.forRoot({name: '__tiptosaveDB'}),
    AngularFireModule.initializeApp(firebaseConfig),
    AngularFireDatabaseModule,
    AngularFireAuthModule,
    TextMaskModule
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage,
    InicioPage,
    LoginPage,
    RegistrarPage,
    EsqueciSenhaPage,
    CrudUsuarioPage
  ],
  providers: [
    Geolocation,
    GooglePlus,
    Facebook,
    StatusBar,
    SplashScreen,
    { provide: ErrorHandler, useClass: IonicErrorHandler },
    { provide: LOCALE_ID, useValue: 'pt-BR' },
    AuthProvider,
    AuxiliarProvider,
    UsuarioProvider
  ]
})
export class AppModule {}

pages/registrar/registrar.module.ts

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { RegistrarPage } from './registrar';

import { ComponentsModule } from '../../components/components.module'

@NgModule({
  declarations: [RegistrarPage],
  imports: [
    ComponentsModule,
    IonicPageModule.forChild(RegistrarPage)
  ],
})
export class RegistrarPageModule {}

pages/registrar/registrar.module.html

<ion-header class="bg-tiptosave">
  <ion-navbar>
    <ion-title>CRIAR CONTA</ion-title>
  </ion-navbar>
</ion-header>
<ion-content padding>
  <div class="subtitulo regular tiptosave-cinza">Falta pouco para você aproveitar os melhores preços da sua região!</div>
  <formulario-usuario></formulario-usuario>
</ion-content>

pages/crud-usuario/crud-usuario.module.ts

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { CrudUsuarioPage } from './crud-usuario';

import { ComponentsModule } from '../../components/components.module'

@NgModule({
  declarations: [
    CrudUsuarioPage,
  ],
  imports: [
    ComponentsModule,
    IonicPageModule.forChild(CrudUsuarioPage)
  ],
})
export class CrudUsuarioPageModule {}

pages/crud-usuario/crud-usuario.module.html

<ion-header class="bg-tiptosave">
  <ion-navbar>
    <ion-title>MEUS DADOS</ion-title>
    <ion-buttons end>
      <button class="header-button" (click)="logout()">Logout</button>
    </ion-buttons>
  </ion-navbar>
</ion-header>
<ion-content padding>
  <formulario-usuario></formulario-usuario>
</ion-content>

1 Like

First off, you probably want to redact your firebase credentials from your post. Secondly, if you are lazily loading pages, you don’t want them in the app module as they are now.

1 Like

Wow, I didn’t saw the firebase credentials are there, thank you.
But, to use components in module pages, I need to put pages in “lazy loading” to work, too?
In this case, remove all pages from app.module and change to string from navController.push() and app.getRootNav().setRoot() is the answer?

1 Like

Yes, although I personally don’t like app.getRootNav() at all, because I consider it to smell of spaghetti.

I’ll do these changes, have another or better way to change a page and prevent back button to return? I use app.get Root Nav() to change root after login/register pages.

What I do for that is to have an authentication status provider that exposes a Subject<boolean>. I subscribe to it in the app component and set the root page there correspondingly. Then anybody can inject it and call next() on the authNotifier and all the interaction with the root nav is confined to the app component.

Interesting, I read the post and make sense, in sometime in this project I will change for your method.
About the subject of this post, worked.
I changed all pages to “lazy loading”, and now, the error is gone, and the component is working in these 2 pages.
Thank you so much about the explanations and answers.

Hello. I have a similar problem, I’m trying to use a component in two pages in a lazy loading ionic app.
I add the import for the component and set it’s declaration in the page.module.ts and this works… but as soon as I do this for a second page I get errors:
Error: Type MyComponent is part of the declarations of 2 modules

Please could you explain your solution… I don’t know where I would use app.getRootNav().setRoot().
Thank you.

Hello,

there are 3 places where you can declare your custom component for using in another page or custom component.

For eager loading in app.module.ts
for lazy loading all in one place: components.module.ts
for lazy loading in each page or custom component where you wanna use it. for example in whateverPage and dummyPage, then in whatever.module.ts and dummy.module.ts.

You can mix eager and lazy loding with different pages or custum components, but can use only one kind of them with same page/custom component.

remove that declaration you do not want to use.

Best regards, anna-liebt