0

I'm a student and just started to learn Angular 7 and .Net Core 2.0

I have created some sessions in my controllers in .Net Core API and need to call them to implement some route protection in angular and so I have made this function in the below image which call the session from API to check whether to allow the route or not in Angular.

enter image description here

This is what my controller looks like

enter image description here

now what happening is when i make a call it hits the controller but because it is asynchronous the execution of angular keeps continuing rather than first waiting for the data to come from API because based on that data my canActivate() function in Angular is going to return true or false, by the time data is fetched and stored in variable my line no. 38 in the image had already been executed and I have set it to be false by default.

please help how to call the data synchronously so that the data is first fetched from the API and then it hits the last line after in Angular.

Amir
  • 28
  • 12

2 Answers2

1

Don't subscribe to the observable and don't store the result in a member variable.

Just return the mapped result as observable, something like this:

canActivate(...) {
    return this.corpService.geSession().pipe(
            map(data => {
                if (data == null)
                {
                    ...
                    return false;
                }
                else
                {
                    ...
                    return data[1] === 'true';
                }
            })
        )
}
sloth
  • 99,095
  • 21
  • 171
  • 219
  • if you don't subscribe, nothing's going to happen (I guess corpService use `HttpClient get`) – Florian Jan 08 '19 at 12:23
  • Depends on the implementation of the service. If you don't call `connect()` on the Observables returned by HttpClient, then yes, you have to subscribe. – sloth Jan 08 '19 at 12:26
1

canActivate returns Observable | Promise | boolean;

You should return Observable<boolean> than boolean and change method to like:

canActivate {
  return this.corpService.getSession().pipe(
    ...

    map(
     res => {
        if(res) {
         return true
        }
         // you can set redirect to permission page (use router.navigate)  

        return false;

     })
  )

}

Ajax is asynchronous. And canActivate prudently will be executed as async.


If I were you in error case on the back-end return 401.

 return Unauthorized(); // instead OK(null)

and handle exception on front-end

canActivate {
      return this.corpService.getSession().pipe(
        ...

        map(res => res),
        catchError((error: HttpErrorResponse) => {
            return Observable.throw(error.statusText);
        }));
      )

}
  • Thanks Konstantin, that solved the problem and also thanks for suggestion in my controller to return unauthorized but i'm not able to use the catch block as you mentioned, it says 'unreachable code detected' may be because i'm returning the function itself, any other suggestion would be appreciated. – Amir Jan 09 '19 at 05:45
  • That worked, returning `ThrowError()` was showing some typecasting error so I referred to this - [link](https://stackoverflow.com/questions/43115390/type-void-is-not-assignable-to-type-observableinput) Thanks once again. – Amir Jan 10 '19 at 03:29