Ionic2: No provider Error - ionic2

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';

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?

How to preview SQLITE db in ionic2 app

I am developing an Ionic2 app. I am using Ionic STORAGE, which uses SQLITE in android. I want to preview that db for debugging. How can I do that. DDMS in android studio shows nothing.
I heard that Stetho is good for android app debugging. But couldn't found any tutorial how to integrate it with Ionic2.
Any help would be appreciated.
Rgds
You can :
console.log() database values and can see then in android studio debugger
Use a browser such as chrome in desktop and see database values(may not use sqllite)
more info
https://developers.google.com/web/tools/chrome-devtools/manage-data/local-storage
Use WebSQL for debugging:
import { Injectable } from '';
import { SQLite } from 'ionic-native';
import { Platform } from 'ionic-angular';
const DB_NAME: string = 'particulars.db';
const win: any = window;
#Injectable()
export class StorageService {
private _db: any;
constructor(private platform: Platform) {
if (this.platform.is('cordova')) {
this._db = new SQLite();
this._db.openDatabase({
name: DB_NAME,
location: 'default' // the location field is required
}).then(() => {
this._tryInit();
});
} else {
console.warn('Storage: SQLite plugin not installed, falling back to WebSQL. Make sure to install cordova-sqlite-storage in production!');
this._db = win.openDatabase(DB_NAME, '1.0', 'database', 5 * 1024 * 1024);
this._tryInit();
}
_tryInit() {
//do query here
}
}
See https://gist.github.com/NickStemerdink/64c782807fc31b7bc9b529ad4b1d56d5.

Ionic 2: How to use custom build Cordova Plugin

I'm already created cordova plugin and already used in Ionic 1, its worked. Then I tried to use it in Ionic 2 but I don't really know how to call that plugin. I follow the step from here to create my own plugin. And this is what i did:
plugin.xml
<name>myPlugin</name>
<js-module src="www/myPlugin.js" name="myPlugin">
<clobbers target="myPlugin" />
</js-module>
myPlugin.js
module.exports = {
myFunction: function (success, failure) {
cordova.exec(success, failure, "myPlugin", "myFunction", []);
}
};
hello-ionic.ts
import { Component } from '#angular/core';
declare var cordova: any;
#Component({
selector: 'page-hello-ionic',
templateUrl: 'hello-ionic.html'
})
export class HelloIonicPage {
constructor() {
}
click() {
if (typeof cordova !== 'undefined') {
cordova.plugins.myPlugin.myFunction();
}
}
}
But unfortunately it return me an error "Undefined myFunction" in hello-ionic.ts.
Here is what I did.
hello-ionic.ts
import { Component } from '#angular/core';
declare var myPlugin: any;
#Component({
selector: 'page-hello-ionic',
templateUrl: 'hello-ionic.html'
})
export class HelloIonicPage {
constructor() {
}
click() {
myPlugin.myFuntion(
(data) => {
console.log(data);
},
(err) => {
console.log(err);
});
}
}
declare var myPlugin: any; , myPlugin name I get from <clobbers target="myPlugin" />.
Note: Need to run the project in device only.
Following tutorial is a good resource to learn how to create custom cordova plugin :
https://taco.visualstudio.com/en-us/docs/createplugintutorial/
I have followed this tutorial to create multiple custom plugins and those are working fine in Ionic2.
One more thing to point out that the tutorial has not mentioned that:
You have to add your custom plugin in your ionic 2 project using following command:
ionic plugin add "folder path of your custom plugin"
Updated:
In your plugin.xml file, you have set "myPlugin" as target in clobbers tag.
So you should call your function as followed
window.myPlugin.myFunction();
Tip: Whenever you use custom plugin created by you(or someone else), inspect the application using Chrome Developer tools. In console tab of developer tools, you can inspect the window and other available objects and can find out correct way to call plugin's methods.

Ionic2: Runtime Error Cannot read property 'prototype' of undefined

I am using Ionic2 and am getting this error:
Runtime Error
Cannot read property 'prototype' of undefined
Reading here and here, it suggests it could be related to the order in which a subclass and baseclass are declared. I am using a baseclass with a subclass. Where do you change the order in which they are declared, is it in the imports? In what file?
Funny thing is my code was working fine, and suddenly started to get this error, even without me changing the base or sub classes. I did make a change to another file, which I have now reverted, but still get the error.
More details:
Error:
main.js:24046Uncaught TypeError: Cannot read property 'prototype' of undefined
at __extends (main.js:24046)
at job.ts:26
at Object.<anonymous> (job.ts:24)
at __webpack_require__ (bootstrap cdd11c2…:19)
at Object.<anonymous> (main.js:46012)
at __webpack_require__ (bootstrap cdd11c2…:19)
at Object.<anonymous> (personModel.ts:21)
at __webpack_require__ (bootstrap cdd11c2…:19)
at Object.<anonymous> (locationModel.ts:11)
Code:
job.ts
import { Component, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef } from '#angular/core';
import { NavController, NavParams, InfiniteScroll, Content, Platform, Events, AlertController, LoadingController, ViewController, PopoverController } from 'ionic-angular';
import { JobModel } from '../model/jobModel';
import { PersonModel } from '../model/personModel';
import { SubCategoryModel } from '../model/subCategoryModel';
import { LocationModel } from '../model/locationModel';
import { RatingModel } from '../model/ratingModel';
import { ReviewPage } from '../review/review';
import { ChatsPage } from '../chats/chats';
import { CategoryPage } from '../category/category';
import { PersonPage } from '../person/person';
import { MyCameraPage } from '../mycamera/mycamera';
import { JobService } from '../service/jobService';
import { PersonService } from '../service/personService';
import { RatingService } from '../service/ratingService';
import { UtilityService } from '../utils/utilityService';
import { SearchJobsParent } from '../searchjobs/searchjobsParent';
import { MapRangeService } from '../service/mapRangeService';
#Component({
selector: 'job',
templateUrl: 'job.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class JobPage extends SearchJobsParent {
#ViewChild(Content) content: Content;
.....
searchJobsParent.ts
...
#Component({
})
export class SearchJobsParent {
...
ionic info
Your system information:
Cordova CLI: You have been opted out of telemetry. To change this, run: cordova telemetry on.
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: Not installed
I solved this by using Composition instead of Inheritance.
You create an instance of the class you have the common functionality in:
myClas.ts
private someCommonClass: SomeCommonClass = null;
...
this.someCommonClass = new SomeCommonClass(platform, ref);
someCommonClass.ts
constructor(platform: Platform)
The very first comment here got me thinking right and led me to a solution. My problem was I was trying to import a class into my base class. The imported class wasn't being bundled in the right order. By switching the order of my import statements in app.component.ts I was able to solve the problem.
In app.component.ts:
Wrong
import { ListPage } from '../pages/list/list';
import { LoginPage } from "../pages/login/login";
This was wrong because ListPage extended AppPage (not listed here) which imported LoginPage.
Right
import { LoginPage } from "../pages/login/login";
import { ListPage } from '../pages/list/list';
this problem happen because you install Native plugin and this plugin extends from IonicNativePlugin for Example (Base64ToGallery, TextToSpeech, ...). So, this caused in conflict, Iremoved this extends and it is work...
Following this steps for Example to TextToSpeech Plugin:
in this Path YourProjectFolder\node_modules\#ionic-native\text-to-speech
open file index.d.ts
go to declaration to class:
export declare class TextToSpeech extends IonicNativePlugin{
/**
* This function speaks
* #param options {string | TTSOptions} Text to speak or TTSOptions
* #return {Promise<any>} Returns a promise that resolves when the speaking finishes
*/
speak(options: string | TTSOptions): Promise<any>;
/**
* Stop any current TTS playback
* #return {Promise<any>}
*/
stop(): Promise<any>;
}
Delete extends IonicNativePlugin and save.
That is all!
Did anybody try to provide a reference file with the correct order like this:
/// <reference path='SomeCommonClass.ts' />
/// <reference path='TheExtendingClass.ts' />

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