Loading config before starting to construct/load rootPage - ionic2

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();
});
}

Related

"__zone_symbol_currentTask":{"type":"microTask","state":"notScheduled","source":"Promise.then","zone":"angular","cancelFn":null,"runCount":0}}

I am getting this error
"__zone_symbol_currentTask":{"type":"microTask","state":"notScheduled","source":"Promise.then","zone":"angular","cancelFn":null,"runCount":0}}
while login facebook from my hybrid application. I have used
ng2-cordova-oauth
plugin to achieve facebook login. My code look like.
import { Component } from '#angular/core';
import {IonicPage, NavController, Platform} from 'ionic-angular';
import {OauthCordova} from '../../../node_modules/ng2-cordova-oauth/platform/cordova';
import {Facebook} from '../../../node_modules/ng2-cordova-oauth/core';
#IonicPage()
#Component({
selector: 'page-facebook',
templateUrl: 'facebook.html',
})
export class FacebookPage {
public oauth: OauthCordova;
private provider: Facebook;
public constructor(public navCtrl: NavController, private platform: Platform) {
this.oauth = new OauthCordova();
this.provider = new Facebook({
clientId: "1807864452579635",
appScope: ['id','story','picture','link','type','full_picture','message']
});
}
public login() {
this.platform.ready().then(() => {
this.oauth.logInVia(this.provider).then((success) => {
alert(JSON.stringify(success));
}, (error) => {
console.log(JSON.stringify(error));
});
});
}
}
I ran into this on a project I was working on too. The problem turned out to be that the ng2-cordova-oauth dependencies weren't installed. Specifically we had to run:
cordova plugin add cordova-plugin-inappbrowser
cordova plugin add cordova-plugin-whitelist
cordova prepare
You may also have to whitelist your site using the information found at https://github.com/apache/cordova-plugin-whitelist
Edit: You can't use ng2-cordova-oauth from the browser. You have to use a device or a simulator.
note that it is unlikely for anyone to see the original error in this code since it in part depends on external dependencies
You can use
JSON.stringify(error,Object.getOwnPropertyNames(e));
to get a clear description of the error you getting, because The __zone_symbol_currentTask is a property inserted into the Error object by Angular and JSON.stringify does not output the Error object's own properties (by default)
see also: Is it not possible to stringify an Error using JSON.stringify?

Ionic 2 Page Change Subscription

How can I subscribe to page changes in Ionic 2? I'd just like to log page names/titles globally. Is there an event I can subscribe to?
create a service
import {Injectable} from '#angular/core';
import {Subject} from 'rxjs/Rx';
#Injectable()
export class RouteNamesService{
constructor(){
}
public name = new Subject();
setRouteName(name){
this.name.next(name);
}
}
in app.component.ts
subscribe to
this.routeNamesService.name.subscribe(name => this.routeName = name);
when you enter in to a component then fire
this.routeNamesService.setRouteName("Settings");
(or) in app.component.ts
#ViewChild(Nav) nav: Nav;
ngAfterViewInit() {
this.nav.viewDidEnter.subscribe((data) => {
console.log(data);
});
}
in data you can get component name

Ionic 2 : EXCEPTION: Unexpected token < in JSON at position 0

I want to send data to my database and when i click on submit button, i get this exeption : EXCEPTION: Unexpected token < in JSON at position 0
I really dont know what to do :/ you can check my code on my github: https://github.com/majlo23/makeorder-ionic
and here is my PHP code: https://github.com/dmikulasova/make-order_server
I had the same error but when i changed the serve response format to JSON, it worked for me.
More details
Node example:
app.get('/', function(req, res, next) {
return res.status(200).json({
message: "success"
});
});
Ionic 2
I generated a service.ts file to define my HTTP request method to be shared with all components.
I defined function load that return an Observable
import {Injectable} from '#angular/core';
import 'rxjs/add/operator/map';
import {Http,Response} from '#angular/http';
import {BackendURL} from '../utils/backendURL';
#Injectable()
export class HomeService {
constructor(private http: Http) {
}
load() {
return this.http.get(BackendURL.host).map((res:Response) => res.json()).catch(BackendURL.handleError);
}
}
In my component, i inject the service and i subscribe to the observable.Now you should see the response logged in the console.
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import {HomeService} from '../../services/home.service';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController,public hs:HomeService) {
console.log('constructor HomePage');
this.hs.load().subscribe((data:any) => console.log('constructor HomePage data',data));
}
}

Ionic 2 - Add a component dynamically to app root

I'm trying to add a custom component dynamically (from a directive) into my Ionic 2 app root...
I've tried many things, but nothing works!
I know that I could add a container with an id to hold my custom component and reach it through an Input in my directive, but I don't want to use that solution.
I need to be able to add any custom component into app root.
This is my last attempt:
import { Directive, ElementRef,
ComponentFactoryResolver,
ViewContainerRef,
ApplicationRef
} from '#angular/core';
import { App, ViewController } from 'ionic-angular';
import { MyComponent } from '../../components/myComponent/myComponent';
#Directive({
selector: '[myDirective]',
host: {
'(click)': 'onClick()',
}
})
export class MyDirective {
myComponent: any;
constructor( private el: ElementRef,
private app: App,
private appRef: ApplicationRef,
private vcr: ViewContainerRef,
private componentFactoryResolver: ComponentFactoryResolver
) {
this.myComponent = this.componentFactoryResolver.resolveComponentFactory(MyComponent);
}
onClick() {
this.app._appRoot._overlayPortal._viewport.createComponent(this.myComponent);
}
}
It should create my component as a sibling of _overlay elementin app root, but I only receive an error message:
No provider for ViewController
What am I doing wrong? Any suggestion or any other solution?

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 ...