-2

I want to create a function that will return true if http.get was successful, otherwise return false. I was trying something like that:

  isOk() {
    let isOk;
    this.http.get('ip/api/isOk')
      .subscribe(x => { isOk = true; }, 
      (err) => { isOk = false; });
    return isOk;
  }

But it returns undefined. I know it's an async function so it returns a value before http.get finishes. How can I create a function that returns true/false after "receiving" data from a REST API?

edit: I want to use this function at Guard canActivate function. I dont know how can I construct IF statement with observable.

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
      let x = this.someService.isOk();
      if(...){//if isOk return true
         return true;
      }else{
        this.router.navigate(['/login']);
      }
  }
blady9565
  • 19
  • 1
  • 9
  • Return an observable and subscribe to where you want to use it later on. – Nicholas K Apr 18 '20 at 14:08
  • The answer is correct, you can't return a value like with with RxJS. Can you show how you are using isOK? Depending on how you are trying to use the value, there could be a way to use the async return value of isOK. – Alexander Staroselsky Apr 18 '20 at 14:08
  • @AlexanderStaroselsky i want to use this function at ```canActivate``` (Guard) function. I want to return true if function was succesfull, otherwise i want to redirect. – blady9565 Apr 18 '20 at 14:21
  • You should have mentioned that. Guards can use asynchronous observable that emit `boolean`. As long as you return `Observable` from isOK(), the guard can use that. – Alexander Staroselsky Apr 18 '20 at 14:23
  • @AlexanderStaroselsky can you show me how? I was trying but.. nothing works. ( i have no idea how to construct IF statement with observable) – blady9565 Apr 18 '20 at 14:25
  • Edit the question to include how you tried exactly to use isOK in your guard (show guard code) and then the question could be re-opened/re-evaluated. – Alexander Staroselsky Apr 18 '20 at 14:26
  • If this is reopened I can provide an answer of using isOK with the guard. – Alexander Staroselsky Apr 18 '20 at 14:57
  • I found solution :) Instead of `subscribe` i used `pipe(map)` and now it works. :) – blady9565 Apr 18 '20 at 15:13

1 Answers1

0

You're trying to mix incompatible things: sync and async code. http.get is async, which means exactly following: in most cases there is no result yet at the moment when your code returns back to caller; that's why undefined is the only reasonable value to return.

Once you stick to async worflow, keep along endlessly. In your particular case you might want to return Observable<boolean> back to caller and let it subscribe() rather then do it yourself. Consoder pipe() and map() or tap() defined to be operators on the Observable<>. The rxjs docs.

Zazaeil
  • 3,900
  • 2
  • 14
  • 31
  • I know :) But i have no idea how to fix it :) And this is actaully my question – blady9565 Apr 18 '20 at 14:08
  • @blady9565 as I mentioned above, do not abandon `Observable<>`. Stick to it as long as possible. Embed your sync code into async workflow represented by your `Observable`. – Zazaeil Apr 18 '20 at 14:10
  • Ok, so how can i use this function at ```canActivate``` (Guard) ? I want to return true if function was succesfull, otherwise i want to redirect. – blady9565 Apr 18 '20 at 14:18
  • canActivate can return the Observable. So, in your canActive will be: `return this.http.get('ip/api/isOk') .subscribe(x => { your logic});` – Danil Sabirov Apr 18 '20 at 14:45
  • @DanilSabirov I was trying something like that but it dont work, I dont know how to return true (redirect works fine). In function ```canActivate``` I had something like that: ` return this.someService.isOk().subscribe((x) => { return true; }, err =>{this.router.navigate(['/login']); }); ` – blady9565 Apr 18 '20 at 14:54