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 ...
Related
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?
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.
I am using Ionic2 rc4.
Your system information:
Cordova CLI: 6.4.0
Ionic Framework Version: 2.0.0-rc.4
Ionic CLI Version: 2.1.18
Ionic App Lib Version: 2.1.9
Ionic App Scripts Version: 1.0.0
ios-deploy version: Not installed
ios-sim version: Not installed
OS: macOS Sierra
Node Version: v6.9.4
Xcode version: Xcode 8.2.1 Build version 8C1002
I would like to add a service. I have other Services, that work perfectly. So I configure this new Service (PayPalService) the same.
payPalTest.ts
import { Component, Inject, forwardRef } from '#angular/core';
import { PayPalService } from '../paypal/PayPalService';
#Component({
templateUrl: 'payPalTest.html'
})
export class PayPalTestPage {
public payPalService: PayPalService = null;
constructor( #Inject(forwardRef(() => PayPalService)) payPalService) {
this.payPalService = payPalService;
}
public payOut(): void {
alert('payOut');
//this.payPalService.payOut();
}
}
payPalService.ts
declare var require: any;
var paypal = require('paypal-rest-sdk');
//import {paypal-rest-sdk} from './paypal-rest-sdk';
import { Injectable } from "#angular/core";
#Injectable()
export class PayPalService {
public paypal: any = null;
constructor() {
}
}
app.module.ts
import { PayPalService } from "../pages/paypal/payPalService";
import { PayPalTestPage } from "../pages/paypal/payPalTest";
...
#NgModule({
declarations: [
...
PayPalTestPage
...
entryComponents: [
...
PayPalTestPage
...
...
providers: [..., PayPalService]
However, I get the following error.
Error
Runtime Error Error in ./MyApp class MyApp - caused by: No provider
for PayPalService!
I think the error is related to the way I import the 'paypal-rest-sdk'.
declare var require: any;
var paypal = require('paypal-rest-sdk');
I installed the paypal-rest-sdk as follows:
npm install paypal-rest-sdk
And the new package has been added to the node_modules.
Question
Can anyone please suggest how I can resolve the above error please?
UPDATE
If I remove all reference to the PayPal api by commenting out the following two lines:
payPalService.ts
// declare var require: any;
// var paypal = require('paypal-rest-sdk');
I get the following error:
Error
Runtime Error Module build failed: Error: ENOENT: no such file or
directory, open
'/Users/richardmarais/Development/ionic/theWhoZoo/src/pages/paypal/payPalService.js'
at Error (native)
It was a really silly mistake by me. The import had the incorrect case.
Change:
payPalTest.ts
import { PayPalService } from '../paypal/PayPalService';
to:
import { PayPalService } from '../paypal/payPalService';
I have been trying to figure out why Globalization.getPreferredLanguage() would fail only when running on an iOS device (not when running on a simulator or Android device / emulator)
Globalization.getPreferredLanguage().then((property) => {
let lang = property.value;
if (lang) {
if (lang.startsWith('en')){
this.translate.use('en_GB');
}
else if (lang.startsWith('fr')) {
this.translate.use('fr_FR');
}
else {
this.translate.use('en_GB');
}
} else {
console.log("property.value is null");
}
}).catch((reason) => {
this.translate.use('en_GB');// <-- not only does this NOT WORK, but the reason given is NetworkError (DOM Exception 19): A network error occurred.
});
What I have tried:
Removing and adding the Globalization plugin with both ionic and cordova instructions:
ionic plugin rm cordova-plugin-globalization && ionic plugin add
cordova-plugin-globalization
sudo cordova plugin rm cordova-plugin-globalization && sudo cordova plugin add cordova-plugin-globalization
EDIT 1
So after more debugging I can see it is the angular ng2-translate 'use' function that is failing. In my app.module.ts:
import { TranslateLoader, TranslateModule, TranslateStaticLoader } from 'ng2-translate/ng2-translate';
...
export function createTranslateLoader(http: Http) {
return new TranslateStaticLoader(http, '/assets/i18n', '.json');
}
...
#NgModule({
declarations: [
...
],
imports: [
...
BrowserModule,
HttpModule,
TranslateModule.forRoot({
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [Http]
}),
...
]
...
})
export class AppModule { }
But in my app.component.ts when I call
this.translate.use('en_GB');
It throws some exception. I have checked and the files do exist in the folder:
/.../platforms/ios/www/assets/i18n
For me, Globalization.getPreferredLanguage() is never resolved. So I am currently using
this.deviceLang = navigator.language;
This returns the device language with its variant like (FR-FR / EN-US)
Im building a ionic 2 rc0 app. My rootPage depends on some configuration I have to load before I start my App. I'm using a provider called Config all over over the application. How can I delay/wait until configs loaded before constructing my Home page component. I need the configs in the constructor of Home. Is there sth. like a preloading module from ionic for situation like that ?
Is that even the best location for tasks like that ?
My Config module uses
http.get(../assets/config/config.json)
.toPromise()
.then(res => this.data = res);
to load the json file locally into data object of of my Config provider. And my code in app.component.ts fires a the function config.loadDefault() to load these default settings from the config.json file for the application .....
app.components.ts
import { Component } from '#angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from 'ionic-native';
import { Home } from '../pages/home/home';
import { Config } from '../providers/config/config';
#Component({
template: `<ion-nav [root]="rootPage"></ion-nav>`
})
export class LoddenApp {
public rootPage = Home;
constructor(
public platform : Platform,
public config : Config
){
// loading config
config.loadDefault()
.then(data => {
console.log(data);
return config.loadSettingsFromDB();
})
.catch(err => {
console.log("error occured while loading config:");
console.log(err);
});
platform.ready().then(() => {
...
});
}
}
By not defining the rootPage until i got back my promise response, I can hold back the constructor of my Home page from firing.
...
export class LoddenApp {
public rootPage : any; // hold back
constructor(
...
Then inside the then() block, i can set the rootPage of my app.
this.rootPage = Home; // Home is the Homepage component
I am not sure this is the best way to do. But one option is to hide the splash screen after your data gets loaded.
import {Splashscreen} from 'ionic-native';
constructor(
public platform : Platform,
public config : Config
){
platform.ready().then(() => {
// loading config
config.loadDefault()
.then(data => {
console.log(data);
return config.loadSettingsFromDB();
})
.catch(err => {
console.log("error occured while loading config:");
console.log(err);
});
Splashscreen.hide();
});
}