Creating toast inside alert causes error


#1

I’m trying to create a toast message when a user presses a button inside an alert that I have created. The problem is when i create a toast inside the button handler in the alert I get an error. I’m pretty sure it has something to do with the app being out of scope, but i’m quite sure how to resolve this problem. I have posted my code below.

Thanks in advance!

  public showForgotPasswordAlert(){
    let passwordRecoveryAlert = this.alertCtrl.create({
      title: "Password Recovery",
      message: "In order to recover your password please enter your email address in the box below.",
      inputs:[
        {
          name:"email",
          placeholder:"Email",
          type:"email"
        },
      ],
      buttons:[
        {
          text: "Cancel",
          handler: () => { passwordRecoveryAlert.dismiss(); }
        },
        {
          text: "Submit",
          handler: this.submitForgotPasswordQuery
        }
      ]
    });

    passwordRecoveryAlert.present();

  }  

//used when the user presses submit on the password recovery alert
private submitForgotPasswordQuery(email: any){

let passwordToast = email.toastCtrl.create({
  message: '',
  duration: 3000,
  position: 'top'
});

let emailEntered = email.email;

if(emailEntered === ""){

  passwordToast.setMessage("Email could not be found. Are you sure this is the correct email?");
  passwordToast.present();

}else{

  passwordToast.setMessage("Please check your email to retrieve your lost password.");
  passwordToast.present();

}
console.log(email);

}

Produces

Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
Native: tried calling StatusBar.styleDefault, but Cordova is not available. Make sure to include cordova.js or run in a device/simulator
EXCEPTION: Error in ./AlertCmp class AlertCmp - inline template:0:1737 caused by: Cannot read property 'create' of undefined
ORIGINAL EXCEPTION: Cannot read property 'create' of undefined
ORIGINAL STACKTRACE:
TypeError: Cannot read property 'create' of undefined
    at Object.SignInPage.submitForgotPasswordQuery [as handler] (sign-in.ts:140)
    at AlertCmp.btnClick (alert-component.js:108)
    at DebugAppView._View_AlertCmp10._handle_click_0_0 (AlertCmp.ngfactory.js:1090)
    at view.js:403
    at dom_renderer.js:249
    at dom_events.js:26
    at t.invoke (polyfills.js:3)
    at Object.onInvoke (ng_zone_impl.js:43)
    at t.invoke (polyfills.js:3)
    at e.runGuarded (polyfills.js:3)
ERROR CONTEXT:
DebugContext {_view: _View_AlertCmp10, _nodeIndex: 0, _tplRow: 0, _tplCol: 1737}
Uncaught Error: Error in ./AlertCmp class AlertCmp - inline template:0:1737 caused by: Cannot read property 'create' of undefined

#2

The error message is telling you it can’t call “create” on undefined. You are calling “create” on this.alertCtrl, so I would look at how and when you are initializing that, because it’s apparently not being done.


#3

Thanks for the suggestion rapropos :slight_smile:. It actually ended up being another issue though. The problem was when using “this” in a button handler without fat arrow syntax “this” refers to the button that the handler is being called from.

Example

  public showForgotPasswordAlert(){
    let passwordRecoveryAlert = this.alertCtrl.create({
      title: "Password Recovery",
      message: "In order to recover your password please enter your email address in the box below.",
      inputs:[
        {
          name:"email",
          placeholder:"Email",
          type:"email"
        },
      ],
      buttons:[
        {
          text: "Cancel",
          handler: () =>  passwordRecoveryAlert.dismiss()
        },
        {
          text: "Submit",
          handler: this.submitForgotPasswordQuery       //-- Refer to this handler
        }
      ]
    });

  //used when the user presses submit on the password recovery alert
  private submitForgotPasswordQuery(email: any){
     let passwordToast = this.toastCtrl.create({        //-- In the above case the "this" here will refer to the "Submit" button in the alert window
        message: 'Whats up everyone how are you',
        duration: 5000,
        position: 'bottom'
      });
   }

Whereas if you wrap the function using a fat arrow it will ensure “this” refers to the context of the current class rather then the button itself.

Example

  buttons:[
    {
      text: "Cancel",
      handler: () =>  passwordRecoveryAlert.dismiss()
    },
    {
      text: "Submit",
      handler: (data) => this.submitForgotPasswordQuery(data)      //Notice the fat arrow here. Ensures "this" inside our submitForgotPasswordQuery function refers to the current class.
    }
  ]

For additional information on this problem refer to the links below
http://stackoverflow.com/questions/20627138/typescript-this-scoping-issue-when-called-in-jquery-callback

https://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html

Hope this helps someone!