ionic info
cli packages: (/usr/local/lib/node_modules)
#ionic/cli-utils : 1.19.2
ionic (Ionic CLI) : 3.20.0
global packages:
cordova (Cordova CLI) : 8.0.0
local packages:
#ionic/app-scripts : 3.1.8
Cordova Platforms : android 6.3.0
Ionic Framework : ionic-angular 3.9.2
System:
Node : v8.11.0
npm : 5.6.0
OS : macOS High Sierra
Environment Variables:
ANDROID_HOME : not set
Misc:
backend : pro
MyProvider
import { Injectable } from '#angular/core';
import { Storage } from '#ionic/storage';
#Injectable()
export class GlobalTokenProvider {
constructor(public storage: Storage) {
console.log('Hello GlobalTokenProvider Provider');
}
getToken() {
let token;
this.storage.get('token').then(data => token = data);
return token
}
}
app.module.ts
import { GlobalTokenProvider } from '../providers/global-token/global-token';
providers: [
...
GlobalTokenProvider,
...
]
usepage.ts
import { GlobalTokenProvider } from '../../providers/global-token/global-token';
constructor(public navCtrl: NavController, public navParams: NavParams,public http:HttpClient,public storage:Storage,public globaltoken:GlobalTokenProvider) {
alert(this.globaltoken.getToken())
}
this storage have token but provider return undefined
how to use storage in provider
In Your Provider just return storage as promise
getToken(){
return this.storage.get('token')
}
In your usepage.ts retrieve like this
this.globaltoken.getToken().then((token)=>{
console.log(token)
})
Related
I'm trying to retrieve a request param from a deeplink to a Ionic 5 application using Deeplink plugin (authorization code provided by authorization server on successful authorization redirection).
Android intent filter seems correctly configured as the app is opening after successful authentication.
I keep having unmatched deeplinks with plugin_not_installed error.
app.module.ts:
import { HttpClientModule } from '#angular/common/http';
import { APP_INITIALIZER, NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { Deeplinks } from '#ionic-native/deeplinks/ngx';
import { SQLitePorter } from '#ionic-native/sqlite-porter/ngx';
import { SQLite } from '#ionic-native/sqlite/ngx';
import { Vibration } from '#ionic-native/vibration/ngx';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { IonicStorageModule } from '#ionic/storage';
import { ApiModule as NumeraApiModule } from '#lexi-clients/numera';
import { OidcUaaModule } from '#lexi/oidc-uaa';
import { AuthModule, OidcConfigService } from 'angular-auth-oidc-client';
import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SettingsService } from './settings/settings.service';
export function loadSettings(config: SettingsService) {
return () => config.load();
}
export function configureAuth(oidcConfigService: OidcConfigService) {
return () => oidcConfigService.withConfig(environment.authentication.angularAuthOidcClient);
}
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
AuthModule.forRoot(),
BrowserModule,
HttpClientModule,
IonicModule.forRoot(),
IonicStorageModule.forRoot(),
NumeraApiModule,
OidcUaaModule,
AppRoutingModule,
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: loadSettings,
deps: [SettingsService],
multi: true,
},
{
provide: APP_INITIALIZER,
useFactory: configureAuth,
deps: [OidcConfigService],
multi: true,
},
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
Deeplinks,
OidcConfigService,
SQLite,
SQLitePorter,
Vibration,
],
bootstrap: [AppComponent],
})
export class AppModule {}
app.component.ts:
import { AfterViewInit, Component, NgZone, OnDestroy, OnInit } from '#angular/core';
import { NavigationEnd, Router } from '#angular/router';
import { App, Plugins, StatusBarStyle } from '#capacitor/core';
import { AppCenterCrashes } from '#ionic-native/app-center-crashes';
import { Deeplinks } from '#ionic-native/deeplinks/ngx';
import { NavController, Platform } from '#ionic/angular';
import { LexiUser, UaaService } from '#lexi/oidc-uaa';
import { Observable, Subscription } from 'rxjs';
import { SettingsPage } from './settings/settings.page';
import { SettingsService } from './settings/settings.service';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'],
})
export class AppComponent implements AfterViewInit, OnInit, OnDestroy {
constructor(
private platform: Platform,
private router: Router,
private idService: UaaService,
private settings: SettingsService,
private navController: NavController,
private deeplinks: Deeplinks,
private zone: NgZone
) {
this.platform.ready().then(async () => {
if (this.platform.is('mobile')) {
const { SplashScreen, StatusBar } = Plugins;
StatusBar.setStyle({ style: StatusBarStyle.Light });
SplashScreen.hide();
}
});
}
ngAfterViewInit() {
if (this.platform.is('mobile')) {
this.deeplinks.routeWithNavController(this.navController, { 'login-callback': SettingsPage }).subscribe(
(match) => {
console.log('Successfully matched route', match);
// Create our internal Router path by hand
const internalPath = '/settings';
// Run the navigation in the Angular zone
this.zone.run(() => {
this.router.navigateByUrl(internalPath);
});
},
(nomatch) => {
// nomatch.$link - the full link data
console.error("Got a deeplink that didn't match", nomatch);
}
);
}
}
}
I got it. My Ionic project is a module in an Angular multi-module project and plugin npm dependencies where added to root package.json.
Moving all Ionic-native related dependencies to package.json in Ionic project folder and running ionic cap sync again solved my problem.
Now the question is How to properly configure a Ionic module in an Angular mono-repo (aka multi-module project)?
I'm trying to add adMobFree to a brand New Ionic 4 project.
I've tried doing this over and over, using different methods and following different tutorials and the result is always the same: the app refuses to run in the iOS Simulator. It just stops at the splash screen.
installation steps
ionic cordova platform add ios
ionic cordova platform add android
ionic cordova plugin add cordova-plugin-admob-free --save --variable ADMOB_APP_ID="ca-app-pub-12345678901234567890"
npm install #ionic-native/admob-free
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { AdMobFree } from '#ionic-native/admob-free/ngx';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
providers: [
StatusBar,
SplashScreen,
AdMobFree,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule { }
ads.service.ts
import { Injectable } from '#angular/core';
import { Platform } from '#ionic/angular';
import { AdMobFree, AdMobFreeBannerConfig } from '#ionic-native/admob-free/ngx';
#Injectable({
providedIn: 'root'
})
export class AdsService {
bannerId: 'ca-app-pub-12345678901234567890';
constructor(
public platform: Platform,
private admobFree: AdMobFree
) { }
showBanner() {
this.platform
.ready()
.then(() => {
const bannerConfig: AdMobFreeBannerConfig = {
id: this.bannerId,
isTesting: false,
autoShow: false
};
this.admobFree.banner.config(bannerConfig);
this.admobFree.banner
.prepare()
.then(() => {
this.admobFree.banner.show();
})
.catch(e => console.log(e));
})
.catch(e => console.log(e));
}
}
home.page.ts
import { Component } from '#angular/core';
import { AdsService } from '../services/ads.service';
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
constructor(
public ads: AdsService
) {
this.ads.showBanner();
}
}
What am I doing wrong?
This SO answer was the solution
https://stackoverflow.com/a/59276508/2101328
For Ionic App with Admob plugin (I've tried just in Ioniv V3) you can
add this in ./config.xml under platform ios to auto populate
app-name-info.plist file at every build time.
<platform name="ios">
<config-file parent="GADApplicationIdentifier" target="*-Info.plist">
<string>ca-app-pub-12345/12345</string>
</config-file>
<config-file parent="GADIsAdManagerApp" target="*-Info.plist">
<true />
</config-file>
... (other lines) ...
</platform>
Does not take me parameters to the other screen
I am trying to get name and email, but it is not running, so the login runs me perfect.
I hope they can help me
The ionic version is as follows:
cli packages: (C:\node\Ionic\taxilurin\node_modules)
#ionic/cli-plugin-cordova : 1.6.2
#ionic/cli-plugin-ionic-angular : 1.4.1
#ionic/cli-utils : 1.7.0
ionic (Ionic CLI) : 3.7.0
global packages:
Cordova CLI : 7.0.1
local packages:
#ionic/app-scripts : 2.1.3
Cordova Platforms : android 6.2.3 browser 4.1.0
Ionic Framework : ionic-angular 3.6.0
System:
Node : v6.11.2
OS : Windows 10
npm : 3.10.10
My code Home - Login:
import { Component } from '#angular/core';
//Importamos los elementos que vamos a utlizar
import { RegistroCPage } from './../RegistroCorpotativo/registroC';
import { RegistroPPage } from './../registroParticular/registroP';
import { RegistroNPage } from './../registroNuevo/registroN';
import { NativeStorage } from '#ionic-native/native-storage';
import { Facebook } from '#ionic-native/facebook';
import { NavController } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
registroCPage = RegistroCPage;
registroPPage = RegistroPPage;
registroNPage = RegistroNPage;
constructor(
private facebook: Facebook,
public navCtrl: NavController,
public nativeStorage: NativeStorage
) {
}
loginFacebook() {
this.facebook.login(['public_profile', 'email'])
.then(rta => {
console.log(rta.status);
if (rta.status == 'connected') {
this.getInfo();
};
})
.catch(error => {
console.error(error);
});
}
getInfo() {
let nav = this.navCtrl;
let env = this;
this.facebook.api('/me?fields=id,name,email,first_name,picture,last_name,gender', ['public_profile', 'email'])
.then(function (user) {
env.nativeStorage.setItem('user',
{
name: user.name,
gender: user.gender,
picture: user.picture
})
.then(function () {
nav.push(RegistroNPage);
}, function (error) {
console.log(error);
})
})
.catch(error => {
console.error(error);
});
}
}
My code de PostLogen:
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { NativeStorage } from '#ionic-native/native-storage';
import { Facebook } from '#ionic-native/facebook';
import { HomePage } from './../home/home';
#Component({
selector: 'page-registroN',
templateUrl: 'registroN.html'
})
export class RegistroNPage {
user: any;
userReady: boolean = false;
constructor(
public navCtrl: NavController,
public fb: Facebook,
public nativeStorage: NativeStorage) {
}
ionViewCanEnter() {
let env = this;
this.nativeStorage.getItem('user')
.then(function (data) {
env.user = {
name: data.name,
gender: data.gender,
email: data.email,
picture: data.picture
};
env.userReady = true;
}, function (error) {
console.log(error);
});
}
doFbLogout() {
var nav = this.navCtrl;
let env = this;
this.fb.logout()
.then(function (response) {
//user logged out so we will remove him from the NativeStorage
env.nativeStorage.remove('user');
nav.push(HomePage);
}, function (error) {
console.log(error);
});
}
}
ionViewCanEnter() method evaluates if router should push page into navigation stack or not. This method should return a boolean (or a Promise of boolean) to do this evaluation.
You actually did not returning a value, so that function is returning undefined and evaluate always as false, so Page can not be entered.
Make this small changes to code to return proper value:
ionViewCanEnter() {
let env = this;
return this.nativeStorage.getItem('user')
.then(function (data) {
env.user = {
name: data.name,
gender: data.gender,
email: data.email,
picture: data.picture
};
env.userReady = true;
return true;
}, function (error) {
console.log(error);
return false;
});
}
I try to use MathJax in my ionic 2 application. I have an error message when I try to build
E:\Users\Renaud\Applisionic\QCM>ionic cordova build android --prod --release
Running app-scripts build: --prod --iscordovaserve --externalIpRequired --nobrowser
[09:56:52] build prod started ...
[09:56:52] clean started ...
[09:56:52] clean finished in 4 ms
[09:56:52] copy started ...
[09:56:52] ngc started ...
Error: Template parse errors:
Can't bind to 'MathJax' since it isn't a known property of 'div'. ("
<ion-content>
<div MathJax [ERROR ->][MathJax]="formulae">{{formulae}}</div>
<button ion-button block color="secondary" (click)="goToR"): ng:///E:/Users/Renaud/Applisionic/QCM/src/pages/adversaire/adversaire.html#11:14
My directive is define in math-jax.ts :
import {Directive, ElementRef, Input, Component} from '#angular/core';
#Directive({
selector: '[MathJax]'
})
export class MathJaxDirective {
#Input('MathJax') MathJaxInput: string;
constructor(private el: ElementRef) {
}
ngOnChanges() {
console.log('>> ngOnChanges');
this.el.nativeElement.innerHTML = this.MathJaxInput;
console.log(this.MathJaxInput);
eval('MathJax.Hub.Queue(["Typeset",MathJax.Hub, this.el.nativeElement])');
}
}
My HTML file adversaire.html :
<ion-content>
<div MathJax [MathJax]="formulae">{{formulae}}</div>
</ion-content>
The file adversaire.ts :
import { Component } from '#angular/core';
#IonicPage({
name: "adversaire"
})
#Component({
selector: 'page-adversaire',
templateUrl: 'adversaire.html'
})
export class AdversairePage {
formulae : String ;
constructor() {
this.formulae="`sum_(i=1)^n i^3=((n(n+1))/2)^2`";
}
My directive is delare in app.module.ts :
import { BrowserModule } from '#angular/platform-browser';
import { ErrorHandler, NgModule } from '#angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '#ionic-native/splash-screen';
import { StatusBar } from '#ionic-native/status-bar';
import { AppReno } from './app.component';
import { HomePage } from '../pages/home/home';
import { MathJaxDirective } from '../directives/math-jax/math-jax';
#NgModule({
declarations: [
AppReno,
HomePage,
MathJaxDirective,
],
imports: [
BrowserModule,
IonicModule.forRoot(AppReno),
],
bootstrap: [IonicApp],
entryComponents: [
AppReno,
HomePage,
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
]
})
export class AppModule {}
I need alertCtrl: AlertController, sanitizer: DomSanitizer, modalCtrl: ModalController, toastCtrl: ToastController on several places in my App. Is there a way to make them global available or do I really have to forward them through all classes, in my case through 4 constructors?
If you declare providers in a module, they will be forwarded to all components under this module. Then, they could be considered as global if you declare them in the app.module.
If what you want is to not import them into each component that need them, the only option I see is to wrap them into a factory provider or a custom one and then import only this new provider :
EDIT : Coding
Global provider example
Test environment :
Cordova CLI: 6.2.0
Ionic Framework Version: 2.0.0-rc.3
Ionic CLI Version: 2.1.8
Ionic App Lib Version: 2.1.4
Ionic App Scripts Version: 0.0.45
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Linux 3.19
Node Version: v6.9.1
Xcode version: Not installed
App
./src/app/app.module.ts :
import { NgModule, ErrorHandler } from '#angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { DefaultModal } from '../modals/default/default.modal';
import {GlobalProvider} from '../providers/global.provider'
#NgModule({
declarations: [
MyApp,
HomePage,
DefaultModal
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
DefaultModal
],
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}, GlobalProvider]
})
export class AppModule {}
Modal
./src/modals/default/default.modal.html :
<ion-header>
<ion-navbar>
<ion-title>{{nav_params.title}}</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list>
<ion-list-header>
Global controller :
</ion-list-header>
<ion-item *ngFor="let controller of nav_params.global_provider_names">
{{controller}}
</ion-item>
</ion-list>
</ion-content>
./src/modals/default/default.modal.scss :
default_modal {
}
./src/modals/default/default.modal.ts :
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { NavParams } from 'ionic-angular';
#Component({
selector: 'default-modal',
templateUrl: 'default.modal.html'
})
export class DefaultModal
{
nav_params
constructor(
private nav : NavController
, private _nav_params : NavParams
)
{
this.nav_params =
{
title : this._nav_params.get(
"title"
)
, global_provider_names : this._nav_params.get(
"global_provider_names"
)
}
}
}
Home page
./src/pages/home/home.html :
<ion-header>
<ion-navbar>
<ion-title>
Home page
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<button
ion-button
(click)="present_alert()"
>
Present alert
</button>
<button
ion-button
(click)="present_modal()"
>
Present modal
</button>
</ion-content>
./src/pages/home/home.scss :
page-home {
}
./src/pages/home/home.ts :
import { Component } from '#angular/core'
import { DefaultModal } from '../../modals/default/default.modal'
import { GlobalProvider } from '../../providers/global.provider'
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(
private _global_provider : GlobalProvider
)
{
}
present_alert()
{
let alert = this._global_provider.alert_controller.create(
{
title: 'Alert title'
, subTitle: 'Alert subtitle'
, buttons:
[
'Dismiss'
]
}
)
alert.present()
}
present_modal()
{
let modal = this._global_provider.modal_controller.create(
DefaultModal
, {
title : 'Modal title'
, global_provider_names : Object.keys(
this._global_provider
)
}
)
modal.present()
}
}
Global provider
./src/providers/global.provider.ts :
import {Injectable} from '#angular/core'
import {AlertController} from 'ionic-angular'
import {ModalController} from 'ionic-angular'
import {ToastController} from 'ionic-angular'
#Injectable()
export class GlobalProvider
{
constructor(
public alert_controller : AlertController
, public modal_controller : ModalController
, public toast_controller : ToastController
)
{
}
}
Hope this helps!