'ion-icon' is not a known element

I see from the RC 0 changelog some stuff changed around Icons inside a Button. But I apparently can’t figure out what I need to change so hoping another set of eyes will determine what I’m missing here.

Prior to RC 0 I had:

<button class="SlogsFooter__HelpButton" (click)="helpClick()">
    <ion-icon
            name="help-circle-outline"
            class="SlogsFooter__HelpIcon">
    </ion-icon>
</button>

After RC 0 I changed to:

<button ion-button icon-only class="SlogsFooter__HelpButton" (click)="helpClick()">
    <ion-icon
            name="help-circle-outline"
            class="SlogsFooter__HelpIcon">
    </ion-icon>
</button>

and I’m getting the error seen in Topic Subject. The above html fragments are wrapped inside an ion-footer for what it’s worth.

What does the module look like that you’re importing this component into and declaring it? Are you importing into the AppModule or a feature module that you created?

-Dharsan

I’ve got a SharedModule that I’m pulling in common used services, components, pipes, etc. Just borrowing from my Angular 2.x web architecture. The SharedModule is being imported into the base AppModule:

@NgModule({
bootstrap : [IonicApp],
imports : [
// browser specific renderers and core directives e.g. ngIf, ngFor, etc
NgReduxModule,

    // ng2-translate
    TranslateModule.forRoot({
        provide     : TranslateLoader,
        useFactory  : (http : Http) => new TranslateStaticLoader(http, 'i18n', '.json'),
        deps        : [Http]
    }),
    IonicModule.forRoot(AppComponent),
    SharedModule.forRoot()
],
declarations    : [
    AppComponent
],
providers       : []

})

1 Like

Ah I think I know the problem. If you are using a component with ionic elements (ion-item etc) in the module you declare them you need to add ‘IonicModule.forRoot(IonicComponent)’ to the input array.

Check out this forum post and you’ll see what I mean.

-Dharsan

5 Likes

yeah you completely lost me :confused: I only know how Angular 2 handles modules so if Ionic 2 somehow deviates from that…

I think what you’re saying is every single time I want to import a component somewhere I need to use the syntax

IonicModule.forRoot(someComponent)

In whatever module I’m importing/declaring the component…is that right???

3 Likes

Yeah it seems that in order to use the ionic specific elements, you need to include IonicModule.forRoot(componentThatUsesIonicElements) in the input array of the NgModule that declares that component.

Example:
Say we have a home page component that has some ionic elements (ion-item etc).

import {Component} from '@angular/core';

@Component({
  templateUrl: 'home.html',
})

export class HomePage {
  constructor() {
    console.log('Home Constructor');
  }

}

Now, say we’re importing that into a module. In this case, we’ll call it HomeModule. It looks like this:

import { NgModule } from '@angular/core';
import { IonicModule } from 'ionic-angular';

import { HomePage } from './home';

@NgModule({
    imports: [
        IonicModule.forRoot(HomePage)
    ],
    declarations: [
        HomePage
    ],
    exports: [
        HomePage
    ]
})
export class HomeModule { }

Note that the example should probably contain CommonModule so you can use ngIf and ngFor and all that good stuff. I just don’t have it there to keep it simple.

So now we need to include that in our AppModule so we can get to the home page:

import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';

import { HomeModule } from '../pages/home/home.module';

@NgModule({
  declarations: [
    MyApp,
  ],
  imports: [
    HomeModule,
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp
  ],
  providers: []
})
export class AppModule { }

This example shows how to include a feature module in your app module and also shows what you need to do in feature modules so that ionic specific elements are recognized.

Hope that makes more sense,
Dharsan

4 Likes

okay, yeah I followed what was happening in the other forum post you linked to. Just worked differently than pure Angular 2 stuff so I wanted to verify :blush:

My app is building now, thanks for taking the time to look at my issue

can you verify if I’m doing this correctly??

Login Feature Module:

import {NgModule} from ‘@angular/core’;
import {IonicModule} from ‘ionic-angular’;

import {SharedModule} from ‘…/…/shared/’;
import {SlogsLoginComponent} from ‘./slogs-login.component’;
import {
SlogsNewUserComponent,
SlogsExistingUserComponent
} from ‘./components/’;

@NgModule({
imports : [
SharedModule,
IonicModule.forRoot(SlogsLoginComponent),
IonicModule.forRoot(SlogsNewUserComponent),
IonicModule.forRoot(SlogsExistingUserComponent)
],
declarations : [
SlogsLoginComponent,
SlogsNewUserComponent,
SlogsExistingUserComponent
],
exports : [
SlogsLoginComponent,
SlogsNewUserComponent,
SlogsExistingUserComponent
],
providers :
})

export class LoginModule {

}

Base Ionic 2 App Module:

@NgModule({
bootstrap : [IonicApp],
imports : [
// Ng2-Redux
NgReduxModule,

    // ng2-translate
    TranslateModule.forRoot({
        provide     : TranslateLoader,
        useFactory  : (http : Http) => new TranslateStaticLoader(http, 'i18n', '.json'),
        deps        : [Http]
    }),
    SharedModule,
    LoginModule,
    IonicModule.forRoot(AppComponent)
],
declarations    : [
    AppComponent
],
providers       : []

})

Getting a ton of errors around some of the components in the SharedModule with this configuration. Basically the component templates blowing up because it doesn’t recognize any of the @Input stuff on the component: "Can’t bind to ‘someProperty’ since it isn’t a known property of ‘some-component’ type stuff over and over :confused:

1 Like

It looks to me like your ngModule stuff is correct.You sure it’s an @Input issue? I poked around on google and it sounds like an ngModel error for most people. If it’s not a typo, I can look at your code if you have a github repository to clone.

-Dharsan

I’m sure it has nothing to do with the @Input per se, just something odd going on with the DI stuff in Angular 2 I imagine. I just wanted to verify that I was on track with how I was configuring my @NgModule stuff.

It seems that Ionic 2.x is every bit as opinionated, if not worse, as Ionic 1.x was :confused: The more I deviate from the starter projects and their app-scripts the more trouble I seem to have, sigh. Throwing everything into a “pages” directory isn’t my idea of elegant but if it makes everything work without issue I may not have much choice I’m afraid.

Thanks for verify my module configs. I’ll do some research on my end and see if I can figure out what is going on. I’ve spent most of the day studying the Angular DI stuff indepth so Im either very prepared to figure out the problem or even more lost than when I started :slight_smile:

The only problem with this is,

inside you custom module,
imports: [IonicModule]

I think it is required for you to have access of ionic components.

13 Likes

You saved my day, I was wondering why my lazy loading components is not recognizing my ion-icon name attribute.

Thank you, your solution is right

thanks, works for me!

i’ve add this in all page.module.ts

but ion-icon still not showing
pls help

import { NgModule } from '@angular/core';
import {IonicModule, IonicPageModule} from 'ionic-angular';
import { SettingHomePage } from './setting-home';
import {AppModule} from "../../../app/app.module";

@NgModule({
  declarations: [
    SettingHomePage,
  ],
  imports: [
    IonicPageModule.forChild(SettingHomePage),
    ...AppModule.imports,
  ],
})
export class SettingHomePageModule {}



//in appmodule
public static imports = [
    IonicModule,
    CommonModule,
    PipesModule,
    DatePickerModule,
    DirectivesModule,
    ComponentsModule
  ];

Your shared components module must be like this:

import { NgModule } from ‘@angular/core’;
import { IonicModule } from ‘@ionic/angular’;
import { CommonModule } from ‘@angular/common’;
import { YourCustomComponent } from ‘./yourcomponentsfolder/yourcustomcomponent.component’;

@NgModule({
imports: [IonicModule, CommonModule],
declarations: [YourCustomComponent],
exports: [YourCustomComponent]
})
export class AppModule { }


In your home.page module:

import { NgModule } from ‘@angular/core’;
import { CommonModule } from ‘@angular/common’;
import { FormsModule } from ‘@angular/forms’;
import { Routes, RouterModule } from ‘@angular/router’;

import { IonicModule } from ‘@ionic/angular’;

import { HomePage } from ‘./home.page’;

import { SharedComponentsModule } from ‘…/…/yourcomponentsfolder/sharedcomponentsmodule.module’;

const routes: Routes = [
{
path: ‘’,
component: HomePage
}
];

@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ComponentsModule,
RouterModule.forChild(routes),
],
declarations: [HomePage]
})
export class HomePageModule {}