Runfast Webmaster
Runfast Webmaster

Reputation: 319

Ionic 2, this.nav.push() is undefined

I come from Ionic 1 and I'm starting with ionic 2. I get an error when I use this.nav.push(nameOftheOterPage) right after a promise but this function this.nav.push is totally working when I use it outside the promise function authHandler:

    import {Page, NavController} from 'ionic-angular';
    import {ItemDetailsPage} from '../item-details/item-details';

    @Page({
      templateUrl: 'build/pages/login/login.html'
    })
    export class LoginPage {
      static get parameters() {
        return [[NavController]];
      }

      constructor(nav) {
        this.nav = nav;
        this.firebaseUrl = "https://MYFIREBASE.firebaseio.com";
        this.authType = "login";
        this.error_username = false;
      }

      login(form) {
      if(form.controls.username.value === null){

        this.error_username = true;
      }
      else{
          /* Authenticate User */ 
          var ref = new Firebase(this.firebaseUrl);
          ref.authWithPassword({
            email    : form.controls.username.value,
            password : form.controls.password.value
          }, this.authHandler);
          }
        }

      authHandler(error, authData) {
        if (error) {
            console.log("Login Failed!", error);
        } else {
            console.log(authData);
            this.nav.push(ItemDetailsPage);
        }
      }
    }

Could you help me with it?

Thanks.

Upvotes: 1

Views: 2161

Answers (1)

Yaron Schwimmer
Yaron Schwimmer

Reputation: 5357

The use of this is a little tricky in javascript objects, especially when callbacks are involved. (I recommend this interesting article about it).

The gist of it, is that you always need to keep track of which object was the one that called the function, because this will be bound to the calling object.

The solution for your problem will be to bind your class' this to the callback, so that this will be what you think it should be. So when you call authWithPassword, do it like this:

ref.authWithPassword({
   email: form.controls.username.value,
   password: form.controls.password.value
}, this.authHandler.bind(this));

Edit
As @Manu Valdés suggested in the comments, another option you have, if you want to avoid the use of bind, is to define authHandler in the following way:

authHandler = (error, authData) => {
    if (error) {
        console.log("Login Failed!", error);
    } else {
        console.log(authData);
        this.nav.push(ItemDetailsPage);
    }
}

This works because in arrow functions, their this is set to that of the outer execution context, no matter who the caller was.

Upvotes: 3

Related Questions