I have a couple of pages and I want to swipe left or right to navigate between them. For example my Tabs component is like :
import { Component } from '#angular/core';
import { HomePage } from '../home/home';
import { Search } from '../search/search';
import { Share } from '../share/share';
import { Notification } from '../notification/notification';
import { Profile } from '../profile/profile';
#Component({
selector: 'hn-tabs',
templateUrl: 'tabs.html'
})
export class TabsPage {
// this tells the tabs component which Pages
// should be each tab's root Page
home: any = HomePage;
search: any = Search;
share: any = Share;
notification: any = Notification;
profile: any = Profile;
constructor() { }
}
and I want to navigate to Search page from Home Page with a SWIPE - LEFT .
Is this possible ?
Please help !!
Related
All the below testing and coding is done for Android phone.
I have created a new tabs project using ionic tabs. And I have 4 tabs at the bottom right now. Now the problem is I clicked on another tab no the view and then try to use the default SwipeToGoBack gesture in the phone and that does nothing.
If I go into any other page then the back gesture works fine, but when I am in the 4 pages of the tabs, it does not work.
I tried below options:
<ion-router-outlet id="main" [swipeGesture]="true"></ion-router-outlet>
IonicModule.forRoot({
swipeBackEnabled: true
}
But those did not help. I can even close the side menu bar opened by swipe back. But can not go to the previous tab by swiping back on phone. Even not able to close the app.
If the application is opened and no other tabs were clicked and I do the swipe back gesture then the app closes, but as soon as I click on other tabs then I can not even come out of the application.
I also tried adding back button listeners from the platform but that also did not help. I added below code part in the tabs.page.ts:
this.platform.backButton.subscribe(() => {
navigator.app.exitApp();
});
Any help on how to go back to the previous tab on swipe back gesture on phone and finally close the app if no previous tab history?
Links already tried:
https://github.com/ionic-team/ionic/issues/12927
Handling hardware back button in Ionic3 Vs Ionic4
Swipe through segment tabs - Ionic 3
export class TabsPage {
navigationProccess:Array<any> = [];
lastTabName:string = "";
currentBack:string = "";
constructor(private platform: Platform,private router:Router,private navctrl:NavController) {
this.router.events.subscribe((event:RouterEvent)=>{
if(event.url !== undefined){
if(this.lastTabName !== event.url && event.url !== this.currentBack){
// we put last tab name not equal event.url so the event don't go twice through array
// we put event.url not equal current back that is since when navcontroll in back button go back its considered a router event and we don't need it to be inserted again
this.pushTabHistory(event.url);
}
this.lastTabName = event.url;
}
});
this.platform.backButton.subscribeWithPriority(99999999,async()=>{
let pushHistoryCount = this.navigationProccess.length;
if(this.router.url.includes('tabs') == true && pushHistoryCount > 1){
let url = this.navigationProccess[pushHistoryCount-2].url;
this.navigationProccess.splice(pushHistoryCount-1, 1);
this.currentBack = url;
//currentBack should be assigned before navgiate back
this.navctrl.navigateBack(url);
}
})
}
pushTabHistory(tabName:string){
let navHistory = {
url:tabName
};
this.navigationProccess.push(navHistory)
}
}
Mate i've edited my answer and you where right.
Tabs don't have routeroutlet.cangoBack() since tabs and tabs/tab1ortab2ortab3 are considered one level and can't go backward.
Here i created the way to make navigation history inside array and go back and forward from this array but subscribe back is from tabs page and i make it like that since you could making it just for testing.
But As an advanced way here we go ->
1) Create A service tabnav:
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class TabnavService {
public navigationProccess:Array<any> = [];
public lastTabName:string = "";
public currentBack:string = "";
constructor() { }
pushTabHistory(tabName:string){
let navHistory = {
url:tabName
};
this.navigationProccess.push(navHistory)
}
}
2)Inside Your TabsPage:
import { TabnavService } from './../services/tabnav.service';
import { Router, RouterEvent } from '#angular/router';
import { Component } from '#angular/core';
import { NavController, Platform } from '#ionic/angular';
#Component({
selector: 'app-tabs',
templateUrl: 'tabs.page.html',
styleUrls: ['tabs.page.scss']
})
export class TabsPage {
constructor(private platform: Platform,
private router:Router,
private tabNavService:TabnavService) {
if(this.platform.is('android')){
this.router.events.subscribe((event:RouterEvent)=>{
if(event.url !== undefined){
if(this.tabNavService.lastTabName !== event.url && event.url !== this.tabNavService.currentBack){
// we put last tab name not equal event.url so the event don't go twice through array
// we put event.url not equal current back that is since when navcontroll in back button go back its considered a router event and we don't need it to be inserted again
this.tabNavService.pushTabHistory(event.url);
}
this.tabNavService.lastTabName = event.url;
}
});
}
}
}
3) In app.component.ts :
import { TabnavService } from './services/tabnav.service';
import { Component, ViewChild } from '#angular/core';
import { Platform, IonRouterOutlet, NavController } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { Router } from '#angular/router';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent {
#ViewChild(IonRouterOutlet,{static:false}) routerOutlet:IonRouterOutlet;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private router:Router,
private navctrl:NavController,
private tabNavService:TabnavService
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
this.platform.backButton.subscribeWithPriority(99999999,async()=>{
let pushHistoryCount = this.tabNavService.navigationProccess.length;
if(this.router.url.includes('tabs') == true && pushHistoryCount > 1){
let url = this.tabNavService.navigationProccess[pushHistoryCount-2].url;
this.tabNavService.navigationProccess.splice(pushHistoryCount-1, 1);
this.tabNavService.currentBack = url;
//currentBack should be assigned before navgiate back
this.navctrl.navigateBack(url);
}else if(this.router.url.includes('tabs') == true && pushHistoryCount <2){
// here is the array less than 2 which is one (you could make it ==0 but i make it if app glitches or something)
//so if app is on main start point it exit on back pressed
navigator['app'].exitApp();
}
});
});
}
}
And Thats All ^^ . Any Help Just comment here again ^^.
I'm working on ionic 4 application. when the user signs In, I added a checkbox to asks for Remember me, so the next time the user open the app it doesn't show the login page and directly forward the user to Home page. I have google and found this. However, while using the accepted solution, I encountered an issue, which it shows the login page for 2 or 3 seconds, then open the Home page. How I can safely achieve it without delay?
app.component.ts
import { SmsVerificationService } from 'src/app/services/SMS/sms-verification.service';
import { Component } from '#angular/core';
import { Platform } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { FCM } from '#ionic-native/fcm/ngx';
import { Plugins, Capacitor } from '#capacitor/core';
import { Router } from '#angular/router';
import { Storage } from '#ionic/storage';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent {
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private fcm: FCM,
private route: Router,
private storage: Storage
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.fcm.getToken().then(token => {
console.log(' token is ', token);
});
this.fcm.onTokenRefresh().subscribe(token => {
console.log('on token refresh ', token);
});
this.fcm.onNotification().subscribe(data => {
console.log(data);
if (data.wasTapped) {
console.log('Received in background');
// this.router.navigate([data.landing_page, data.price]);
} else {
console.log('Received in foreground');
// this.router.navigate([data.landing_page, data.price]);
}
});
this.storage.get('isLogined').then(data => {
if (data)
this.route.navigateByUrl('/main-tab');
})
this.statusBar.styleDefault();
this.splashScreen.hide();
if (Capacitor.isPluginAvailable('SplashScreen')) {
Plugins.SplashScreen.hide();
}
});
}
}
The codes that are supposed to change the page
this.storage.get('isLogined').then(data => {
if (data)
this.route.navigateByUrl('/main-tab');
})
Do you have a separate login component? If so, you can create and add a guard to your login component to navigate to your main page when Remember me was checked.
I am a beginner in Ionic and I am developing an app which requires a user to sign in before he places an order.
Right now, if the user tries to place an order and he is not signed in, I need a logic where I can redirect him to the login page and on success, I can redirect him back to the order page. This would have been possible in android using start activity for the result. But how can I achieve this in Ionic?
I have a solution of opening the login page using modal and dismissing it on success but I do not want to implement that solution as of now.
Here is an example whcih open modal via login. Path and IonicPage should be adjusted before using the below code. Maybe you can get a point from the code.
home.ts
import { Component } from '#angular/core';
import { AuthProvider } from '../../providers/auth/auth.provider'
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public authService:AuthProvider) {
}
goToOrder(){
this.authService.openModalViaLogin('OrderPage', {}, ()=>{})
}
}
login.ts
import { Component } from '#angular/core';
import { IonicPage, ViewController } from 'ionic-angular';
import { AuthProvider } from '../../providers/auth/auth.provider';
#IonicPage()
#Component({
selector: 'page-login',
templateUrl: 'login.html',
})
export class LoginPage {
constructor(public authService:AuthProvider, public viewCtrl:ViewController) {
}
login(){
this.authService.isAuthenticated = true;
this.viewCtrl.dismiss()
}
close(){
this.viewCtrl.dismiss()
}
}
auth.provider.ts
import { Injectable } from '#angular/core';
import { ModalController } from 'ionic-angular';
#Injectable()
export class AuthProvider {
public isAuthenticated:boolean = false;
constructor(public modalCtrl:ModalController) {
console.log('Hello AuthProvider Provider');
}
public openModalViaLogin(modalPage:string, params:any, callbackOnDidDismissed:Function){
if(this.isAuthenticated){
let modal = this.modalCtrl.create(modalPage,params)
modal.onDidDismiss(()=>{
callbackOnDidDismissed()
})
modal.present()
}else{
let loginModal = this.modalCtrl.create('LoginPage')
loginModal.onDidDismiss(()=>{
if(this.isAuthenticated){
let modal = this.modalCtrl.create(modalPage,params)
modal.onDidDismiss(()=>{
callbackOnDidDismissed()
})
modal.present()
}else{
console.log("failed to authenticate")
}
})
loginModal.present()
}
}
}
p.s. I think there is a more flexible way to achieve it by nav but that can be quite confusing with this short anwser.
Good evening. I am trying to handle notification click in such a way that when the user click on a notification, a specific page of my application is opened.
I am using FIREBASE COULD MESSAGING AND IONIC 3
Here is the code of the app.component.ts file in witch the code for handling notification is written :
import { Platform, Nav, ToastController } from 'ionic-angular';
import { HomePage } from '../pages/home/home';
import { Component, ViewChild } from '#angular/core';
import { FCM } from '#ionic-native/fcm';
import { Signup } from '../pages/signup/signup';
#Component({
templateUrl: 'app.html',
selector: 'Myappname',
})
export class MyApp {
#ViewChild(Nav) nv: Nav;
rootPage: any = HomePage;
constructor(public fcm: FCM, platform: Platform) {
platform.ready().then(() => {
fcm.onNotification().subscribe(data => {
if (data.wasTapped) {
this.nv.push(Signup);
} else {
console.log("Received in foreground");
}
})
});
}
}
When the nofication is received on the mobile device, if the user click on it, only the home page is displayed and he is note redirected to the signup page as specified in the code.
Any helps ?
Thanks.
I finally found the solution. as i was using firebase cloud functions to send the notification, here is the code i used to make the onNotification() work when a user click on the notification received.
exports.Hello = functions.database.ref('/users/{userId}').onCreate(event=>{
admin.messaging().sendToTopic('all', {
data:{
"key1": value1,
"key2": value2
},
notification: {
clickAction : "FCM_PLUGIN_ACTIVITY",
sound : "default",
title : "Notification title",
body : "message content"
}
});
});
So We must set clickAction property of the notification object to FCM_PLUGIN_ACTIVITY to make onNotification() method execute when the user tapped on the notification.
Here is a code exemple for the app.component.ts in witch the onNotification() method is implemented.
import { Platform, Nav, ToastController } from 'ionic-angular';
import { HomePage } from '../pages/home/home';
import { Component, ViewChild } from '#angular/core';
import { FCM } from '#ionic-native/fcm';
import { Signup } from '../pages/signup/signup';
#Component({
templateUrl: 'app.html',
selector: 'Myappname',
})
export class MyApp {
#ViewChild(Nav) nv: Nav;
rootPage: any = HomePage;
constructor(public fcm: FCM, platform: Platform) {
platform.ready().then(() => {
fcm.onNotification().subscribe(data => {
if (data.wasTapped) {
this.nv.push(Signup);
} else {
console.log("Received in foreground");
}
})
});
}
}
AND now, it works fine !
Try setting the root page as the signup page, hopefully it will work:
this.nv.setRoot(Signup);
and if that doesnt work try adding this before your fcm.onNotification()
var $this = this;
and then use $this to reference inside your if statement // (wasTapped)
$this.nv.setRoot(Signup);
Consider this scenario. I have an ionic2 app and I am using the the FCM plugin for push notifications. Now let us say a push notification arrives when the app is in the background. User, views the notification in the App drawer and then clicks the notification for further information. I would like the user to navigate to a particular path using this.nav.push(PushPage). How can I tap into the notification click event?
app.component.ts
import { Component,ViewChild } from '#angular/core';
import { Platform,NavController,AlertController } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { FCM } from '#ionic-native/fcm';
import { HomePage } from '../pages/home/home';
import {PushPage} from '../pages/push/push';
declare var FCMPlugin;
#Component({
templateUrl: 'app.html',
providers :[FCM]
})
export class MyApp {
rootPage:any = HomePage;
#ViewChild(NavController) nav;
constructor(platform: Platform, statusBar: StatusBar, splashScreen:
SplashScreen,private fcm: FCM,
private alertCtrl: AlertController) {
platform.ready().then(() => {
statusBar.styleDefault();
splashScreen.hide();
fcm.subscribeToTopic('marketing');
fcm.getToken().then(token=>{
})
fcm.onNotification().subscribe(data=>{
if(data.wasTapped){
console.log("Received in background");
this.nav.push(PushPage);
} else {
console.log("Received in foreground");
this.nav.push(PushPage);
};
})
fcm.onTokenRefresh().subscribe(token=>{
this.nav.push(PushPage);
})
fcm.unsubscribeFromTopic('marketing');
});
}
}