How to set two different splash screen? - ionic-framework

How can i set two different splash screens according to package name.
platform.ready().then(() => {
translate.setDefaultLang('az');
translate.use('az');
statusBar.hide();
splashScreen.hide();
localStorage.setItem('companyKey', this.companyToken);
this.appVersion.getPackageName().then(packageName => {
if(packageName.indexOf('app.business') > -1) {
this.rootPage = LoginPage
} else if(localStorage.getItem('selectedTags')) {
this.rootPage = LandingPage;
}
});
}
I can only check package name when platform is ready.

Related

Events in Ionic v4

I'm using Ioni v4Beta and I'm traying to update the sidemenu when the user is login.
I search but the usual solution is use Events:
Ionic 3 refresh side menu after login
https://ionicframework.com/docs/api/util/Events/
But in the new version I don't find it, and I don't know how to do it
https://beta.ionicframework.com/docs/api
Thanks a lot, but I finally find how to import it:
import { Events } from '#ionic/angular';
Example on how to do it with subjects:
export const someEvent:Subject = new Subject();
export class ReceivingClass implements OnDestroy, OnInit
{
private someEventSubscription:Subscription;
public OnInit():void{
someEventSubscription = someEvent.subscribe((data) => console.log(data);
}
public onDestroy():void{
someEvent.unsubscribe();
}
}
export class SendingClass implements OnInit
{
public OnInit():void{
setTimeout(() => {
someEvent.next('hi');
}, 500);
}
}
Are you aware that Ionic v4 events will be deprecated soon?
I was also trying to update the sidemenu when a user logs in as well, so i tried using: import { Events } from '#ionic/angular';
However I got a warning referring me to this link https://angular.io/guide/observables#basic-usage-and-terms which I failed to follow because am not that familiar with observables.
After much research I found that I can still use events but I had to import them from angular's router directive.
This was my code before:
/* import was */
import { Events } from '#ionic/angular';
import { Storage } from '#ionic/storage';//ignore this import if doesn't apply to your code
/* inside the class */
constructor(
private events: Events,
private storage: Storage
) {
this.events.subscribe("updateMenu", () => {
this.storage.ready().then(() => {
this.storage.get("userLoginInfo").then((userData) => {
if (userData != null) {
console.log("User logged in.");
let user = userData.user;
console.log(user);
}
else {
console.log("No user found.");
let user = {};
}
}).catch((error)=>{
console.log(error);
});
}).catch((error)=>{
console.log(error);
});
});
}
changes i made that actually got my code working and deprecation warning gone:
/* import is now */
import { Router,RouterEvent } from '#angular/router';
import { Storage } from '#ionic/storage';//ignore this import if it does't apply to your code
Rest of code
constructor(
public router: Router,
public storage: Storage
){
this.router.events.subscribe((event: RouterEvent) => {
this.storage.ready().then(() => {
this.storage.get("userLoginInfo").then((userData) => {
if (userData != null) {
/*console.log("User logged in.");*/
let user = userData.user;
/*console.log(this.user);*/
}
else {
/*console.log("No user found.");*/
let user = {};
}
}).catch((error)=>{
console.log(error);
});
}).catch((error)=>{
console.log(error);
});
});
}
I got the idea after seeing this https://meumobi.github.io/ionic/2018/11/13/side-menu-tabs-login-page-ionic4.html. I hope my answer can be useful.
Steps to resolve the issue
import events in login page and in sidemenu view
In login page, after login success do your logic to publish the events.
for eg:
this.authService.doLogin(payload).subscribe((response) => {
if (response.status) {
this.storage.set('IS_LOGGED_IN', true);
this.events.publish('user:login');
}
}, (error) => {
console.log(error);
});
In sidemenu view, create a listener to watch the events 'user:login'
for eg:
this.menus = [];
// subscribe events
this.events.subscribe('user:login', () => {
// DO YOUR LOGIC TO SET THE SIDE MENU
this.setSidemenu();
});
// check whether the user is logged in or not
checkIsUserloggedIn() {
let isLoggedIn = false;
if (this.storage.get('IS_LOGGED_IN') == '' ||
this.storage.get('IS_LOGGED_IN') == null ||
this.storage.get('IS_LOGGED_IN') == undefined) {
isLoggedIn = false;
} else {
isLoggedIn = true;
}
return isLoggedIn;
}
// to set your sidemenus
setSidemenu() {
let isUserLoggedIn = this.checkIsUserloggedIn();
if(isUserLoggedIn) {
this.menus = ['Home', 'Aboutus', 'Contactus', 'My Profile', 'Logout'];
} else {
this.menus = ['Login', 'Home', 'Aboutus', 'Contactus'];
}
}

hard time upgrading navigation part of Ionic3 code to ionic4 using router

hi this is my first question in stackoverflow, any help is highly appreciated:
basically my code displays two pages where navigation can be done on same page or to other page.I am finding no way to upgrade my code to Ionic4 using router.
my service.ts in Ionic3 is:
_oneNav: Nav = null;
get oneNav(): Nav {
return this._oneNav;
}
set oneNav(value: Nav) {
this._oneNav = value;
}
_twoNav: Nav = null;
get twoNav(): Nav {
return this._twoNav;
}
set twoNav(value: Nav) {
this._twoNav = value;
}
_isOn: boolean = false;
get isOn(): boolean {
return this._isOn;
}
set isOn(value: boolean) {
this._isOn = value;
}
pushTwo(page: any, params: any) {
console.log("pushTwo",this.isOn);
(this.isOn) ?
this.twoNav.setRoot(page, params):
//this.twoNav.push(page, params);
this.oneNav.push(page, params);
}
pushOne(page: any, params: any) {
this.oneNav.push(page, params);
}
setRootOne(page: any, params: any) {
this.oneNav.setRoot(page, params);
}
onSplitPaneChanged(isOn) {
// set local 'isOn' flag...
this.isOn = isOn;
// if the nav controllers have been instantiated...
if (this.oneNav && this.twoNav) {
(isOn) ? this.activateSplitView() :
this.deactivateSplitView();
}
}
activateSplitView() {
let currentView = this.oneNav.getActive();
if (currentView.component.prototype
instanceof _TwoPage) {
// if the current view is a 'Two' page...
// - remove it from the 'one' nav stack...
this.oneNav.pop();
// - and add it to the 'two' nav stack...
this.twoNav.setRoot(
currentView.component,
currentView.data);
}
}
deactivateSplitView() {
let twoView = this.twoNav.getActive();
if(!twoView){
return;
}
if (twoView.component.prototype instanceof _TwoPage) {
// if the current two view is a 'Two' page...
let index = this.oneNav.getViews().length;
// add it to the one view...
this.oneNav.insert(
index,
twoView.component,
twoView.data
);
}
}
app.html is:
<ion-content>
<ion-split-pane (ionChange)="service.onSplitPaneChanged($event._visible);">
<ion-nav [root]="onePage" #oneNav></ion-nav>
<ion-nav [root]="twoPage" #twoNav main></ion-nav>
</ion-split-pane>
</ion-content>
i tried to import RouterOutlet from #ionic/angular but no success
You need read the Ionic 4 migration guide where they defined routing migration also.
As i know default ionic routing (Push/pop) has been changed to angular routing and now you can rout to other page with href='link'.

How save data permanently with Ionic 3?

I'm trying to make an introduction page that will read a QR Code, save the code and pass to another page. This will occur only the first time you open the application. When closing the app and reopen, the introduction page should not appear. So, what is my problem? I'm saving the code I read, but when I close the app and open again, the code that I had saved was lost and the introduction page appears. How do I solve this?
My IntroPage code is:
import { NativeStorage } from '#ionic-native/native-storage';
const STORAGE_KEY = 'hospitals';
...
scannedCode:string = null;
constructor(private navCtrl: NavController,
private barcodeScanner: BarcodeScanner,
private nativeStorage: NativeStorage,
private toast: Toast) {}
public scanCode() {
this.barcodeScanner.scan().then(barcodeData => {
this.scannedCode = barcodeData.text;
if (this.scannedCode === "123"){
this.save(this.scannedCode);
this.navCtrl.push(LoginPage);
}
else{
this.makeToastMessage('Invalid Hospital!', '5000', 'bottom');
}
}, (err) => {
console.log('Error: ', err);
});
};
private save(val){
console.log('data added ' + val);
this.nativeStorage.setItem(STORAGE_KEY, {property: val})
.then(
() => console.log('Stored item!'),
error => this.makeToastMessage('Error storing item', '5000', 'center')
);
};
And my app.component.ts code is:
import { NativeStorage } from "#ionic-native/native-storage";
const STORAGE_KEY = 'hospitals';
...
rootPage:any;
constructor(platform: Platform, statusBar: StatusBar,
splashScreen: SplashScreen, public push: Push,
public alertCtrl: AlertController,
private nativeStorage: NativeStorage) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
this.pushsetup();
this.setRootPage();
});
}
private setRootPage(){
let localStorage:string = "Not got";
this.nativeStorage.getItem(STORAGE_KEY)
.then(
item => localStorage = item.properity,
error => console.log("Error getting item. Error: " + error)
);
alert(localStorage);
switch (localStorage){
case "123":
this.rootPage = LoginPage;
break;
default:
this.rootPage = IntroPage;
break;
}
}
It is not lost. You are checking the value outside your promise then function so it might be executed before data is fetched.
You need to either use the switch case within then where you are looking for the data or chain the promises.
private setRootPage(){
let localStorage:string = "Not got";
this.nativeStorage.getItem(STORAGE_KEY)
.then(
item => localStorage = item.properity,
error => console.log("Error getting item. Error: " + error)
).then(_=>{
switch (localStorage){
case "123":
this.rootPage = LoginPage;
break;
default:
this.rootPage = IntroPage;
break;
}
});
}
This will ensure you will check the value only after the value is fetched from the storage.
Or in short:
private setRootPage(){
this.nativeStorage.getItem(STORAGE_KEY)
.then(
item => {
switch (item.property){
case "123":
this.rootPage = LoginPage;
break;
default:
this.rootPage = IntroPage;
break;
}
},
error => console.log("Error getting item. Error: " + error)
)
}

Ionic push view over modal (need to login)

I have a mobile app where the user needs to re-login after some time for security reasons. The thing is that the content that was open in the background needs to stay there, and open after the login. So, even if it was a modal.
What is the best way to do this.
Pushing the login view when a modal is open doesn't help, since the view is put behind the modal.
Thanks in advance!
on the current page
public openLogin() {
let loginModal = this.modalController.create(LoginPage, { modal: true });
loginModal.present();
loginModal.onDidDismiss(data => {
if (data) {
this.profileData = data;
} else {
}
});
};
on loginPage
this.userService.login(username, password)
.subscribe(
data => {
console.log(data);
if (data.success) {
var user = data.result;
this.userService.setSession(user);
if (this.itsModal) {
this.closeModal(data)
}
else {
this.gotoHome();
}
} else {
// error handling
}
},
error => {
console.log(error);
}
);
public closeModal(data: any = null) {
this.viewController.dismiss(data);
}

one signal additional data in ionic 2/3

I'm trying to work with one signal plugin in my ionic 2 app
I've installed Onesignal and it was working fine,but i don't know how to work with handleNotificationOpened function
there is no document at all (nothing was found)
this is my code:
this.oneSignal.handleNotificationReceived().subscribe((msg) => {
// o something when notification is received
});
but I have no idea how to use msg for getting data.
any help? link?
tank you
Here is how i redirect user to related page when app launch from notification.
app.component.ts
this.oneSignal.handleNotificationOpened().subscribe((data) => {
let payload = data; // getting id and action in additionalData.
this.redirectToPage(payload);
});
redirectToPage(data) {
let type
try {
type = data.notification.payload.additionalData.type;
} catch (e) {
console.warn(e);
}
switch (type) {
case 'Followers': {
this.navController.push(UserProfilePage, { userId: data.notification.payload.additionalData.uid });
break;
} case 'comment': {
this.navController.push(CommentsPage, { id: data.notification.payload.additionalData.pid })
break;
}
}
}
A better solution would be to reset the current nav stack and recreate it. Why?
Lets see this scenario:
TodosPage (rootPage) -> TodoPage (push) -> CommentsPage (push)
If you go directly to CommentsPage the "go back" button won't work as expected (its gone or redirect you to... who knows where :D).
So this is my proposal:
this.oneSignal.handleNotificationOpened().subscribe((data) => {
// Service to create new navigation stack
this.navigationService.createNav(data);
});
navigation.service.ts
import {Injectable} from '#angular/core';
import {App} from 'ionic-angular';
import {TodosPage} from '../pages/todos/todos';
import {TodoPage} from '../pages/todo/todo';
import {CommentsPage} from '../pages/comments/comments';
#Injectable()
export class NavigationService {
pagesToPush: Array<any>;
constructor(public app: App) {
}
// Function to create nav stack
createNav(data: any) {
this.pagesToPush = [];
// Customize for different push notifications
// Setting up navigation for new comments on TodoPage
if (data.notification.payload.additionalData.type === 'NEW_TODO_COMMENT') {
this.pagesToPush.push({
page: TodoPage,
params: {
todoId: data.notification.payload.additionalData.todoId
}
});
this.pagesToPush.push({
page: CommentsPage,
params: {
todoId: data.notification.payload.additionalData.todoId,
}
});
}
// We need to reset current stack
this.app.getRootNav().setRoot(TodosPage).then(() => {
// Inserts an array of components into the nav stack at the specified index
this.app.getRootNav().insertPages(this.app.getRootNav().length(), this.pagesToPush);
});
}
}
I hope it helps :)