Problem to call setRoot in my Alert callback


#1

I have a login page and a home page. After I click the login, I call setRoot to my home page. This is fine.

In my Home page, there is a “Logout” button. When I click it, I’ll setRoot to my Home page inside my alert’s callback. Here is my code:

let confirm = Alert.create({
  title: 'Confirm',
  body: 'Are you sure to log out?',
  buttons: [
    {
      text: 'Yes',
      handler: () => {
        this.nav.setRoot(LoginPage);
      }
    },
    {
      text: 'No',
      handle: () => {
        console.log('No clicked.Do nothing!');
      }
    }
  ]
});
this.nav.present(confirm);

But screen go blank when I click “Yes”. It will be fine when I click “Yes” again.

Any idea? Thanks.


#2

What do you mean with double ‘yes’? does 2 alerts come up?

Are there any logs in the console? both in browser and the cli?

The issue could be with the this context, you should set it to another variable outside the alert create and use that in the handler, i like using this_ref.

I don’t have this kind of issues as i wrap the alert create with a Promise and that handler would be inside the .then() call.


#3

Yes, there will be two alerts come up. It turns to blank screen after I click “Yes” this first time. The alert comes up again. It will be fine when I click “Yes” again this time.

By the way, I tried to set this to this_ref outside alert create, but got the same problem.

Thanks anyway.


#4

If blank screen shows up between or in the first alert is because you don’t give enough time between closing the first and showing the second alert, that messes up the overlay and then you get the blank screen.


#5

But why there are two alerts in the first place? I only create and present it once.


#6

No idea, can’t infer enough from the code you just showed, if you make a gist with the files involved maybe i could help.


#7

You’re right. It maybe due to multi-thread issue. The following code works:

      handler: () => {            
        setTimeout(function () {
          this_ref.nav.setRoot(LoginPage);
        },500);
      }

But I know it’s not an elegant solution.


#8

I’m actually doing the same with a confirm alert, it’s due to transitioning to the new page before closing the alert, my timeout is about 200 ms.

I avoid using any alert before transition or even too son after page load, i wrapped the nav.present(alert) in 50 ms delay to avoid that kind of error when transitioning to new page if that one can show an alert from start.

It actually looks to be with the same purpose as yours, to send the user to LoginPage.


#9

For me, the timeout only works when viewing in a browser, it fails on my android device…


#10

Device is slower, often times you would have to use longer timeouts for slower devices, i think this shouldn’t be happening and have filled at least 3 issues related to Alert (prior name popups).


#11

Has anyone found a proper solution to this issue? It’s still happening and seems like the screen shouldn’t go blank!

Additionally, it behaves differently in iOS!

Anyone?


#12

Have you tried dismissing the alert manually in your code e.g alert.dismiss() or something and waiting for that to happen before setting the root page? That might help (just a guess though)


#13

How would you do this given this code?:

  confirmLogout() {
    let confirm = Alert.create({
      title: 'Confirm Logout',
      message: 'Really logout?',
      buttons: [
        {
          text: 'Cancel',
          handler: () => {
            console.log('Disagree clicked');
          }
        },
        {
          text: 'Logout',
          handler: () => {
            this.logout();
          }
        }
      ]
    });
    this._nav.present(confirm);
  }

#14

I just checked the docs and you can’t dismiss an alert like that. I was thinking of modal which has the dismiss method. Sorry.


#15

No worries. I notice you’re in Horsham, we’re in Falmer. Next time just come fix it for me, thanks :slight_smile:


#16

Small world! Have you tried using an event instead i.e subscribe to it in app.js and publish it when you close your alert. I’ve no idea why that might work but its the sort of thing I’d try! :slightly_smiling: Maybe setting the root when the event has fired might do it? See here for details if you’ve not used Events. http://ionicallyspeaking.com/2016/03/05/publishing-and-subscribing-to-events-in-ionic-2/


#17

Funnily enough, that’s exactly what I did in the first place:

app.ts:

this._events.subscribe('logout', () => {
  this._LoginService.logOut();
  this._SessionService.logOut();
  this.showMenu = false;
  this.getNav().setRoot(LoginPage);
});

then in the controller class (whichever hits the logout button):

  logout() {
    setTimeout(() => {
      this._events.publish("logout", null);
    }, 1000);    
  }

Wrapping the publish event in the timeout fixed the blank screen issue (for now!).

Great minds :grinning:


#18

@zhouhaowowtv What do you mean with this_ref ? How do you define it ?
Thanks


[Solved] Setting rootNav shows blank white screen on iOS
#19

@zhouhaowowtv I hope you got answer of your question.

but still, if you are finding for elegant solutions then this might be right for you.

timeOut in ionic 2


#20

import AlertController,

in construcor add
public alertCtrl: AlertController

confirmDelete() {
let alert = this.alertCtrl.create({
title: ‘Confirm Delete’,
message: ‘Really Delete?’,
buttons: [
{
text: ‘Cancel’,
handler: () => {
console.log(‘Disagree clicked’);

              }
          },
          {
              text: 'Delete',
              handler: () => {
                  this.deletedata();
              }
          }
      ]
  });
  alert.present();

}

delete(){
//function goes here