Uncaught (in promise): false when using ionViewCanEnter

Hi all,

Having trouble getting ionViewCanEnter to work. Either setting a simple variable to false or using a promise I get the following error:

Uncaught (in promise): false

Here is an example of what I’m doing:

export class HomePage {

  canEnter: boolean = false;

  constructor(
    public authService: Auth,
    public navCtrl: NavController) {
      // 
  }

  ionViewCanEnter() {
    console.log('ionViewCanEnter');
    if (this.canEnter) {
      return true;
    } else {
      return false;
    }
    // this.authService.isAuthenticated().then((res) => {
    //     return true;
    // }, (err) => {
    //     return false;
    // });
  }

}

Here is my current build:

Ionic Framework: 2.3.0
Ionic App Scripts: 1.1.4
Angular Core: 2.4.8
Angular Compiler CLI: 2.4.8

Thanks

According documentation:

ionViewCanEnter

boolean/Promise

Runs before the view can enter. This can be used as a sort of “guard” in authenticated views where you need to check permissions before the view can enter

So if your isAuthenticated method return a void promise you could do

ionViewCanEnter() {
   return this.authService.isAuthenticated();
}

otherwise something like

 ionViewCanEnter() {
    return new Promise((resolve, reject) => {
        this.authService.isAuthenticated().then((res) => {
             resolve();
        }, (err) => {
             reject(err);
       });
    });
 }

P.S.: I’m guessing never tried. Note also the second part of code is even probably better with a subscribe instead of ().then…

Thanks for your reply.

I’ve tried both suggestions before posting the ticket and get the same result

Uncaught (in promise): false

Did you deleted these return true; and false; you had before?

Yes, heres the class

export class HomePage {

  constructor(
    public authService: Auth,
    public navCtrl: NavController) {
      // 
  }

  ionViewCanEnter() {
    console.log('ionViewCanEnter');
    return new Promise((resolve, reject) => {
        this.authService.isAuthenticated().then((res) => {
             resolve();
        }, (err) => {
             reject(err);
       });
    });
  }

}

:frowning: sorry to hear that … would you like to try to send a promise< boolean >? I know the doc says < void > but who knows…

like

 ionViewCanEnter() {
console.log('ionViewCanEnter');
return new Promise((resolve, reject) => {
    this.authService.isAuthenticated().then((res) => {
         resolve(true); // <==== Here true
    }, (err) => {
         reject(false); // <===== Here false
   });
});

}

replace reslove() with reslove(true);

this.authService.isAuthenticated().then((res) => {
             resolve(true);
        }, (err) => {
             reject(err);
       });

@reedrichards lol we commentet both at the exactly samte time the same thing :smiley: nice

@lukasrein97 haha yes nice move :wink:

for the record, the doc says Promise< void >, so if that works, means the doc isn’t up-to-date

it woks i have the same thing in my code as well. I dont know if it works for others but for me it works. :slight_smile:

1 Like

@lukasrein97 @reedrichards

Thanks for the suggestions

ionViewCanEnter() {
    return new Promise((resolve, reject) => {
        this.authService.isAuthenticated().then((res) => {
             resolve(true);
        }, (err) => {
             reject(false);
       });
    });
  }

Unfortunately I’m getting the same error:

Error: Uncaught (in promise): false
at v (http://localhost:8100/build/polyfills.js:3:4864)
at s (http://localhost:8100/build/polyfills.js:3:4289)
at http://localhost:8100/build/polyfills.js:3:3997
at ti.reject (http://localhost:8100/build/main.js:43400:23)
at t.invoke (http://localhost:8100/build/polyfills.js:3:9655)
at Object.onInvoke (http://localhost:8100/build/main.js:36908:37)
at t.invoke (http://localhost:8100/build/polyfills.js:3:9606)
at e.run (http://localhost:8100/build/polyfills.js:3:7019)
at http://localhost:8100/build/polyfills.js:3:4661
at t.invokeTask (http://localhost:8100/build/polyfills.js:3:10284)
at Object.onInvokeTask (http://localhost:8100/build/main.js:36899:37)
at t.invokeTask (http://localhost:8100/build/polyfills.js:3:10220)
at e.runTask (http://localhost:8100/build/polyfills.js:3:7637)
at i (http://localhost:8100/build/polyfills.js:3:3707)
at XMLHttpRequest.invoke (http://localhost:8100/build/polyfills.js:3:11437)

I’m a little out of idea. How and when do you push your view?

maybe @lukasrein97 could compare with his working code if he doesn’t mind

I’m not programatically pushing to the view but just using a link in ion-nav.

I want to check if the user is authenticated before the view enters. I suspect when it works and it matches false that it cancels the routing.

Something like (its an example with login credentials like i have in my application):

ionViewCanEnter(){
 this.authService.login(this.loginCredentials).subscribe(allowed => {
      if (allowed) 
      {
          //if you only want to push a page with the back button in it
          this.nav.push(Page2);
          //if you want to generally move to other MAIN Page
          this.nav.setRoot(Page2);
      }
   }
}

and in your authService youll add the login function (i use http post but it works with get also):

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Http } from '@angular/http';
import 'rxjs/add/observable/throw';

........................

  public login(credentials) 
  {
    if (credentials.email === "" || credentials.password === "") 
    {
      return Observable.throw("Please insert credentials!");
    } 
    else 
    {
      return Observable.create(observer => {
        var url = 'http://yourAPIorServer/User_Login.php';
        this.http.post(url, credentials).subscribe((rsp) => {
          //if the user is authentificated "access" is the output of the server as text
          this.accessgranted = rsp.text(); //i use text but you can use rsp.json as well
          let access = (this.accessgranted === 'access');
          observer.next(access);
          observer.complete();
        });
      });
    }

Its only an example with Login Credentials but you can do it all without. But with this method youll get access == true or accees == false back.

1 Like

Hi i m facing the same issue with ionic 2.3.0

let p = new Promise((resolve, reject) => {

  let requirements = Observable.forkJoin(
    this.getCart(),
    this.getPaymentMethods(),
    this.getCurrentUser()
  );
  requirements.subscribe((data) => {
    console.log(data);
    resolve(true);
  }, (error) => {
    console.log(error);
    reject(false);
  })

});
return p;

Test

ionViewCanEnter() {
  return Promise.resolve(true); // does not work
}

or

ionViewCanEnter() {
  return Promise.resolve(); // does not work too
}

@lukasrein97 your implementation is almost identical to mine. Can you confirm what version of Ionic you are on?

Ionic Framework 2.0.0
Ionic Native 2.9.0

Must be broken in Ionic Framework: 2.3.0

There is an open issue

3 Likes