8

I have a working angular2 guard with a canActivate() that calls a service for isLoggedIn() and returns a promise which then resolves and the route is handled appropiately.

However, I am trying to do the opposite, see when the user is not logged in, and it isn't working.

I tried something as simple as this (adding a ! operator), hoping it would work:

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(private authService: AuthService) {}

    canActivate() {
        return !this.authService.isLoggedIn();
    }
}

However, this always returns a falsey value and the route never activates.

This is a relevant excerpt of my isLoggedIn() function:

isLoggedIn(): Promise<Boolean> {
  var component = this;
  return new Promise((resolve, reject) => {       
      component.queryForUser((user) => {
        resolve(user != null);
      });
    }
  });
}

If the user is not equal to null, then he is logged in and the promise resolves with true. Else, false.

While I could simply add a parameter to specify which state I am looking for, or even create a isNotLoggedIn() function, with the same logic but inverted, I ask, Is there a way to negate the value of the promise's resolve for the canActivate()?

1
  • Treat a promise like a promise. .then(...) Commented Apr 5, 2017 at 23:18

3 Answers 3

12

return !this.authService.isLoggedIn() won't work, because of how JS works. this.authService.isLoggedIn() is promise object and is truthy. !this.authService.isLoggedIn() will always be false.

Instead, promise result should be mapped to negated result with

canActivate() {
    return this.authService.isLoggedIn().then(result => !result);
}

Or

async canActivate() {
    return !(await this.authService.isLoggedIn());
}

The parentheses around await ... are optional and used for readability.

2
  • I'm new to TypeScript. So far I've used the => operator in (a) => (sth(a)) as a shorthand for function(a) { sth(a) }. What is => doing in this case? Is it the same thing, just even shorter? Commented Apr 5, 2017 at 23:28
  • 1
    Strictly saying, it's function(a) { return sth(a) }, implicit return should always be kept in mind, because it can ruin things. Yes, it is a shorthand for one param. It's a matter of taste to use it or not. I personally don't use it in my own style guide because it is inconsistent (the inconsistency is discussed here in particular stackoverflow.com/a/41086381/3731501). Commented Apr 5, 2017 at 23:34
5

All you need to do is some further manipulation of the promise's resolved value:

canActivate() {
    return this.authService.isLoggedIn().then(loggedIn => !loggedIn);
}
4

And if you're inside an if statement and async/await is enabled move the negation inside the parenthesis.

if (!await client.bucketExists('test')) {}

Not the answer you're looking for? Browse other questions tagged or ask your own question.