Set a different root page on click of hardware back button


#1

I am trying to set a different root page on pressing the hardware back button on a specific page, I am using this method this.platform.registerBackButtonAction to change the default action

Here is my use case:
This (image below) is MyProfile page (not a root page), where a user can toggle between 2 profiles (Free mode and Restricted Mode) and the user can also check Personal details (this navigates to a different page). The scenario here is when a user chooses any of the modes, and when the user goes back I want the user to land up in respective root pages (FreeMode and RestrictedMode). Now I have managed to set the root page when the user taps the back button on the NavBar.

This is my ts code.

import { Component, ViewChild } from '@angular/core';
import { NavController,Platform, Navbar , List} from 'ionic-angular';
import { ToastController } from 'ionic-angular';
import { NativeStorage } from '@ionic-native/native-storage';
import { FreeModePage } from '../free-mode/free-mode';
import { RestrictiedModePage } from '../restricted-mode/restricted-mode';
@Component({
selector: 'page-profile',
templateUrl: 'profile.html'
})
export class ProfilePage {  
//@ViewChild(Content) content: Content;
@ViewChild(Navbar) navBar: Navbar;
@ViewChild(List) list: List;

public unregisterBackButtonAction: any;
  constructor(public navCtrl: NavController, private nativeStorage : NativeStorage, private toastCtrl : ToastController, private platform : Platform,
  ) {
    
  }
  ionViewDidLoad()
  {
    this.navBar.backButtonClick = (e:UIEvent)=>{
      if(this.selectedProfile == 'FreeMode'){
        this.nativeStorage.setItem("userProfile", { userProfileType: this.selectedProfile });
        this.navCtrl.setRoot(FreeModePage)        
      } if(this.selectedProfile == 'RestrictedMode'){
        this.nativeStorage.setItem("userProfile", { userProfileType: this.selectedProfile });
        this.navCtrl.setRoot(RestrictiedModePage);      
      }  
    return true;
     // this.navCtrl.pop();
     }

     this.customHardwareBackButton()
    
   // this.scrollBottom();
  }
 ionViewCanLeave() {
  //this.unregisterBackButtonAction && this.unregisterBackButtonAction();
  }
  
  customHardwareBackButton():void
  {
    this.platform.registerBackButtonAction(function(event){

      if(this.selectedProfile == 'FreeMode'){
        this.nativeStorage.setItem("userProfile", { userProfileType: this.selectedProfile });
        this.navCtrl.setRoot(FreeModePage)        
      } if(this.selectedProfile == 'RestrictedMode'){
        this.nativeStorage.setItem("userProfile", { userProfileType: this.selectedProfile });
        this.navCtrl.setRoot(RestrictiedModePage);     
        }  
         // this.navCtrl.pop();
       
  }, 1); 
  }
}

Now the real issue is, my hardware back button’s default action is blocked, but it doesn’t navigate and set the rootpage. That’s where I am stuck.

I also cannot use ionViewCanLeave() method as it will trigger and navigate to rootpage when I tap PersonalDetails link. Please help me out on this one.
https://i.stack.imgur.com/ApKeD.png


#2

@scorpion3 What is shown if you put a console.log() in the event?

this.platform.registerBackButtonAction(function(event){

    console.log('selectedProfile', this.selectedProfile);

    if (this.selectedProfile == 'FreeMode') {
    ...

First, see if the event is called. If it’s called, the log will show. Then, see if the value of selectedProfile is assigned and is valid (FreeMode or RestrictedMode).


#4

You pointed it out correctly, I get undefined, any idea why that happens? how do I get access to those variables, also I cant even set a root page even that is undefined ex: if I do this this.navCtrl.setRoot(RestrictiedModePage); I get undefined for RestrictedModePage


#5

@scorpion3 I highly recommend using lambda/arrow functions (those with => so that this is correctly scoped:

this.platform.registerBackButtonAction(event => {

    console.log('selectedProfile', this.selectedProfile);

    if (this.selectedProfile == 'FreeMode') {
    ...

Two factors influenced the introduction of arrow functions: shorter functions and non-binding of this.

More info:


About the undefined page, I don’t understand. Do you mean that the reference RestrictiedModePage is undefined, although you import it and your IDE/Editor show no errors?

Try to log it in your function:

console.log('RestrictiedModePage', RestrictiedModePage);

It should show a function in your browser console (because classes end up as javascript functions).

Are you using @IonicPage(). If you are, you should use a string instead of the class reference in the setRoot() and push() methods; if you aren’t, what you did should work.

Can you show your ts file (I don’t need the code inside the class, just the imports, the annotaions (@) until export class RestrictiedModePage ... {


#6

Thanks a ton! I completely missed that, arrow function concept. It worked!