IonicPage is not working - ionic2

I am using instructions at IonicPage Documentation
But I am getting the following error:
Error: /app/src/pages/subscribe-channel/subscribe-channel.ts has a
#IonicPage decorator,
but it does not have a corresponding "NgModule" at /app/src/pages/subscribe-channel/subscribe-channel.module.ts
To be specific, I made the following changes prescribed in the docs:
added IonicPageModule.forChild(SubscribeChannelPage)
added #IonicPage() on the component i.e. SubscribeChannelPage
I am unable to share code sample, since it is part of the larger application.
A similar error is reported here:
Page has a #IonicPage decorator, but it does not have a corresponding "NgModule"
IonicPage is commented out in the answer suggested there to get rid of this error. However, I am trying to make use of IonicPage and would like to know how to make it work.
Here is subscribe-channel.ts
import { Component, OnInit } from '#angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { IonicPage } from 'ionic-angular';
#IonicPage()
#Component({
selector: 'page-subscribe-channel',
templateUrl: 'subscribe-channel.html'
})
export class SubscribeChannelPage implements OnInit {
constructor() {
}
ngOnInit() {
}
}
and here is app.modules.ts
import { NgModule, ErrorHandler, APP_INITIALIZER } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { HttpModule } from '#angular/http';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { IonicPageModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { SubscribeChannelPage } from '../pages/subscribe-channel/subscribe-channel';
#NgModule({
declarations: [
MyApp,
SubscribeChannelPage
],
imports: [
BrowserModule,
HttpModule,
IonicModule.forRoot(MyApp),
IonicPageModule.forChild(SubscribeChannelPage)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
SubscribeChannelPage
],
providers: [
StatusBar,
SplashScreen,
{ provide: ErrorHandler, useClass: IonicErrorHandler }
]
})
export class AppModule { }
#gerdi, suggestions in the answer helped in avoiding the compilation errors. However, the deep-link still does not work, it takes to default page.
FYI, the deep-link was working earlier with following code in app.module.ts . However, I am trying the IonicPage assuming it is a better option for future.
IonicModule.forRoot(MyApp, {}, {
links: [
{ component: SubscribeChannelPage, name: 'subscribe', segment: 'subscribe/:channelId' },
]
}),

In order to use #IonicPage(), the "component page" that you add the decorator to needs to have a connected module.
The error you are getting is basically saying.
You have added the #IonicPage() decorator but there is no associated module for this component. You need to include a subscribe-channel.module.ts file that declares this component in its own module scope.
So you need to add a subscribe-channel.module.ts which is the declaration of a module.
To better understand this you can go into your terminal and generate a new template and see the files that it adds
>_ ionic generate page foobar
Under the foobar folder, you will see 4 files one of them is foobar.module.ts which is the module declaration.
FYI: You need to change
import { IonicModule } from 'ionic-angular';
to
import { IonicPageModule } from 'ionic-angular';
in the generated template. There still seems to be a few issues around this new shiny stuff

However, the deep-link still does not work, it takes to default page.
FYI, the deep-link was working earlier with following code in app.module.ts . However, I am trying the IonicPage assuming it is a better option for future.
For deeplinking you have to now set it in IonicPage() decorator of your required ionic page.
Remove
links: [
{ component: SubscribeChannelPage, name: 'subscribe', segment: 'subscribe/:channelId' },
]
as this was before IonicPage was introduced in ionic 3.x
Try:
#IonicPage({
name: 'SubscribeChannelPage',
segment: 'subscribe/:channelId'
})
in subscribe-channel.ts.
Example Url will be:
http://localhost:8101/#/subscribe/:channelId

The file name of the module is the same as the component:
- login.ts
- login.module.ts
The module needs to be named login in order to correspond.

Related

Ionic3 lazy loaded modules entry components

In my Ionic app I have a page called "MyCustomer". MyCustomer page has the following IonicPage Config:
#IonicPage({
name: 'MyCustomer',
})
From MyCustomer page I will be opening a component called "CustomerEdit" in modal. So I have defined the CustomerEdit component in MyCustomer Page module file in both declarations and entry components and below is the #NgModule code for Page
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { CommonModule } from '#angular/common';
import { MyCustomerPage } from './my-customer.page';
import { CustomerEdit } from '../../components/CustomerEdit/CustomerEdit';
#NgModule({
declarations: [
MyCustomerPage,CustomerEdit
],
imports: [
CommonModule,IonicPageModule,
IonicPageModule.forChild(MyCustomerPage),
],
entryComponents:[CustomerEdit]
})
export class MyCustomerPageModule {}
When I try to open the CustomerEdit component in modal like this
Open(){
let modal=this.modalCtrl.create(CustomerEdit);
modal.present();
}
I get the following error.
No component factory found for CustomerEdit. Did you add it to #NgModule.entryComponents?
What am I doing wrong here?

In Ionic 2, version 3.0.1 how do I create a custom component that uses Ionic components?

In Ionic 2, how do I create a custom directive that uses Ionic components?
This answer doesn't work anymore.
import {IONIC_DIRECTIVES} from 'ionic-angular'
this also doesn't work. How can i create a custom component that uses Ionic components in Ionic 2, version 3.0.1?
If you stuck with this problem after using lazy loading you should do that like that:
Add IonicModule to 'imports' parameter of CustomComponentModule
Use ionic components in custom components' templates
Add CustomComponentModule to 'imports' parameter of your AnotherComponentModule where you want use that component (CustomComponentModule).
deletable.module.ts
import { NgModule } from '#angular/core';
import { DeletableItem } from './deletable';
import { IonicModule } from 'ionic-angular';
#NgModule({
declarations: [
DeletableItem
],
imports: [
IonicModule
],
exports: [
DeletableItem
]
})
export class DeletableModule {}
bill.html
<ion-content padding>
<ion-list>
<ion-item *ngFor="let bill of bills" (click)="openEdit(bill)">
<ion-label text-left>{{bill.name}}</ion-label>
<ion-label text-right>{{bill.amount}}</ion-label>
<deletableItem></deletableItem>
</ion-item>
</ion-list>
</ion-content>
bill.module.ts
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { BillPage } from './bill';
import { DeletableModule } from './../../components/deletable/deletable.module'
#NgModule({
declarations: [
BillPage
],
imports: [
IonicPageModule.forChild(BillPage),
DeletableModule
],
exports: [
BillPage
]
})
export class BillModule {}
That's work for me.

Ionic 2 lazy loading components

My app is really big and has like 30 components and pages, I load all of them in my app.module.ts and sometimes the application turn slow. I wonder if it has anything to do it.
My question: What's the correct way to lazy load components and use angular 2 features (more modules) with Ionic 2?
Since Ionic 3, you can lazy load components.
Simply, create a new module for each component/page.
Here's an example of how a module of the HomePage should look like:
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
#NgModule({
declarations: [MyApp, HomePage],
imports: [ ... ],
bootstrap: [IonicApp],
entryComponents: [MyApp, HomePage],
providers: [ ... ]
})
export class AppModule {}
After creating the module, attach #IonicPage() to the component:
import { Component } from '#angular/core';
import { IonicPage } from 'ionic-angular';
#IonicPage()
#Component(... )
export class HomePage { ... }
Now you can use your page/component as a string without using the import statement:
rootPage:any = 'HomePage';
for more descriptibe answer, check out this Ionic Lazy Loading blog post.

Ionic 2 rc0 whitescreen (No provider for ConnectionBackend!)

I started a new ionic 2 rc0 app by copying the files of my old beta11 project. I did the necessary steps as described under
Copying your Project to a New Project : ionic 2 rc0 changelog
Now finally after getting no more compiler errors when I run
ionic run android -c
I'm just getting a whitescreen on my android phone.
Chrome debug is logging me
Uncaught Error: No provider for t!
When I'm running
ionic serve -c
the firefox logs me
Unhandled Promise rejection: No provider for ConnectionBackend! ;
Zone: ; Task: Promise.then ; Value: Object { ...
app.module.ts looks like:
import { NgModule } from '#angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { Storage } from '#ionic/storage'; // special thing
import { Http } from '#angular/http';#
// other imports ....
#NgModule({
declarations: [
MyApp,
// PAGES
// MODALS
// CUSTOM COMPONENTS
// DIRECTIVES
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
// PAGES
// MODALS
],
providers: [
Storage,
Http,
// SERVICES/PROVIDERS
]
})
export class AppModule {}
I'm guessing there is something wrong with a provider somewhere, but I just can't find a solution ...
System : ubuntu 16.04 / node v6.7.0 / npm v3.10.3
EDIT :
I started a new sidemenu project with
ionic start debugProject sidemenu --v2
I did this to to debug the providers by sequentially adding the providers of my original Project. It appears that, when I inject the first provider called "Config" in the constructor of app.components.ts
import { Component } from '#angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from 'ionic-native';
import { TabsPage } from '../pages/tabs/tabs';
// PROVIDERS -> providers
import { Config } from '../providers/config/config';
#Component({
template: `<ion-nav [root]="rootPage"></ion-nav>`
})
export class MyApp {
rootPage = TabsPage;
constructor(
platform : Platform,
config : Config <-------------(HERE !!! )
) { .....
I get the the Error message like before:
Unhandled Promise rejection: No provider for ConnectionBackend! ;
Zone: ; Task: Promise.then ; Value: Object { ...
config.ts
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
// providers
import { Http } from '#angular/http';
//import { DB } from '../db/db';
#Injectable()
export class Config {
public data : any;
constructor(
public http : Http,
//public db : DB
){
this.data = {};
}
loadDefault() {
this.data = {
..........................
// DATA OBJECT DEFINITIONS
...........................
};
return Promise.resolve("default settings applied");
}
loadSettingsFromDB(){
return Promise.resolve("no local settings from db for now");
}
// TODO: send settings to server
saveSettingsToDB(settings){
return Promise.resolve("cant save settings for now");
}
handleError(err) : void {
// error stacktrace gets returned on development mode
try{
err = err.json();
}catch(e){}
var msg = err.message || "LOADING ERROR";
if(err.error){
msg += err.error;
//Toast.showLongBottom(msg).subscribe();
}else{
//Toast.showShortBottom(msg).subscribe();
}
console.log("ERROR in config.ts");
console.log(msg);
console.log(err);
}
}
any ideas ? if not, any experience about opening a new issue on github ?
I found the solution. It seems like I can't/shouldn't use the Http module in the providers array in app.modules.ts (In beta11 this was not a problem). My Config module relied on Http, so after constructing Config the application Error (No provider for ConnectionBackend) fired ...

Failed: No provider for Config! (Icon -> Config) in Ionic2 unit tests with karma and jasmin

I'm writing unit tests for an ionic2 app but I get following error when the template contains some ionic elements
e.g.
<ion-icon > </ion-icon>
Failed: No provider for Config! (Icon -> Config)
Any idea?
I don't see how the previous solution works, because Config needs App, which needs Platform, which needs Keyboard which needs... maybe it is because you do not configure testing module asynchronously, which you should ;) simply try this:
import { IonicModule } from 'ionic-angular';
import { YourTestedComponent } from './pathto.component.ts'
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ IonicModule.forRoot(this) ], // this loads ionic deps
declarations: [ YourTestedComponent ],
});
}));
This should fix it
Best of luck
you're not allowed to use template in #app, try to use templateUrl: 'build/app.html' and create a app.html with your tags in it.
I run into the same problem. This worked for me:
import { async, ComponentFixture, TestBed } from "#angular/core/testing";
import { Config, IonicModule } from "ionic-angular";
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
],
imports: [
IonicModule,
],
providers: [
Config,
],
});
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
});