Angular2 authguards encountering issues when trying to run asynchronous functions

I need a way to safeguard my routes by verifying if a user is logged in from the server, but I'm facing issues with asynchronous functions not executing properly.

Below is the code snippet that's causing trouble:

canActivate (route: ActivatedRouteSnapshot , state: RouterStateSnapshot): Observable<any> {
  let permission = route.data[ "permission" ];
   if(permission){
       ..execute another function which works
    )
  }else{
    return this.checkLogin();
  }
}

Regarding the checkLogin function:

checkLogin (url?: string): any {
  this.authService.checkLoggedin()
    .subscribe(
      res=>{
       if(res){
         return true;
       }else{
          this.router.navigate ( [ '/login' ] );
          return false
       }

    }
  )
}

Moving on to the auth service:

checkLoggedin():Observable<any> {
//validate user's login status using server call
  return this._httpclient.get(this.authurl + "/default/is-loggedin")
    .map(res => {

        return res.json().data;
    },error=>{
      return Observable.of(false);
      }
    );
}

Could someone point me in the right direction regarding where I might be making mistakes?

Answer №1

validateLogin should always return either an Observable<boolean> or a Promise<boolean> (or simply a boolean if it operates synchronously). Your current implementation is not returning anything.

To rectify this issue, consider the following approach. Instead of using subscribe, utilize map to transform the value emitted by checkLogStatus() and then encapsulate the boolean value in the returned Observable.

validateLogin(url?: string): Observable<boolean> {
    return this.authService.checkLogStatus()
    .map(
      res=>{
       if(res){
         return true;
       }else{
          this.router.navigate(['/login']);
          return false;
       }
    });
}

Additionally, it's advisable to refrain from declaring functions as returning any; specify the actual return type instead. This practice enables the compiler to detect instances where a return statement is missing when one is required.

Similarly,

checkLogStatus(): Observable<any>
ought to be written as
checkLogStatus(): Observable<boolean>
for improved error detection (potentially necessitating JSON data conversion).

Answer №2

When the navigation is successful, this.router.navigate() resolves to true, meaning that you are indeed returning true.

https://angular.io/api/router/Router

It is advisable to place the router.navigate method within the else block of your canActivate function after calling checklogin and evaluating its outcome.

Answer №3

Here is an alternative approach to consider:

function verifyAccess(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        let permission = route.data[ "permission" ]; //permissions are assigned to routes
       return !permission ? true : this.checkLoggedin()
                    .map((res: any) => {
                        if (res) {
                            return true;
                        }

                        throw new Error('User not logged in!');
                    })
                    .catch(() => {
                        this.router.navigate(['/login']);
                        return Observable.of(false);
                    });
            }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Solving Checkbox Change Event Issue in Angular

I'm having difficulty testing the checkbox-change event for a particular component. Here is the code for the component that needs to be tested: import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: &a ...

Invoking a method in a derived class upon completion of asynchronous logic within the base class

Currently, I am in the process of building an Angular application. One aspect of my project involves a class that extends a base class. While this approach may not be ideal, I am curious to know what would be the best practice for BaseClass to trigger me ...

Secure higher order React component above class components and stateless functional components

I have been working on creating a higher order component to verify the authentication status of a user. Currently, I am using React 15.5.4 and @types/react 15.0.21, and below is a simplified version of my code: import * as React from 'react'; i ...

Comparing dates in Angular 6 can be done by using a simple

Just starting with angular 6, I have a task of comparing two date inputs and finding the greatest one. input 1 : 2018-12-29T00:00:00 input 2 : Mon Dec 31 2018 00:00:00 GMT+0530 (India Standard Time) The input 1 is retrieved from MSSQL database and the in ...

Tips for creating a TypeScript-compatible redux state tree with static typing and immutability:

One remarkable feature of TypeScript + Redux is the ability to define a statically typed immutable state tree in the following manner: interface StateTree { readonly subState1: SubState1; readonly subState2: SubState2; ...

How to effectively merge DefaultTheme with styled-components in TypeScript?

I am facing an issue with integrating a module developed using styled-components that exports a theme. I want to merge this exported theme with the theme of my application. In my attempt in theme.ts, I have done the following: import { theme as idCheckThe ...

Utilize @ngrx/store to merge various reducers from feature modules

I'm currently immersed in developing a test app to delve deeper into the @ngrx/store framework. Within this project, I've set up a module called TrainingModule that aims to store various exercises and related information. The code is functioning ...

This TypeScript error occurs when the type of a CSS file lacks an index signature, resulting in an implicit 'any' type for the element

Currently in the process of transitioning a React app to utilize Typescript. Encountering an error message that reads: ERROR in [at-loader] ./src/components/Services/Services.tsx:34:29 TS7017: Element implicitly has an 'any' type because typ ...

What sets apart the various download options for Typescript, such as npm, NuGet, and Marketplace?

While working in VS Pro, I am a beginner developer in TypeScript (as well as React and Node...). I am focused on truly understanding how these technologies integrate and function together, rather than simply copying commands and code snippets into files. ...

Subscribe to a new Observable once the previous one completes

I need assistance in getting the current user after logging in. When I use this.router.navigate([this.returnUrl]); it does not work. Can someone please help me identify what is wrong here and how I can fix it? onSubmit(): void { this.authService.logi ...

I am encountering issues with running my tests using react-testing-library alongside TypeScript

Currently facing issues with react-testing-library in my TypeScript-based React project. Despite researching and following various tutorials, I am unable to resolve the problem. I have experimented with changing configurations in babel.config.js, tsconfig ...

The execution of the start script has encountered an error

Angular: 5.0.1 / Angular CLI: 1.5.0 / Node: 8.9.1 / npm: 5.5.1 / Os: win32 x64 Executed "npm start" in the terminal/command prompt and encountered the following error. I have been struggling to fix it for a whole day with no success. Can anyone assist me ...

Unable to find solutions for all parameters needed by a CustomComponent within Angular

Whenever I attempt to compile the project for production, an error pops up: There is a problem resolving all parameters for EmployeeComponent in C:/.../src/app/employee/employee.component.ts: (?, ?, ?). Oddly enough, when I run the application, every ...

How can I properly format an Angular locale date for API consumption?

I am currently utilizing two-way binding within my template-driven form: ts: searchLeaveApplication: any = {}; html: <mat-form-field class="searchInputs"> <input matInput [matDatepicker]="searchStartDate" [(ngModel)]="this.search ...

Properly specifying the data type for a generic type variable within a function in TypeScript

As I work on my express project, I am currently coding a function called route. const morph = (params: Function[]) => (req: Request) => params.map(f => f(req)) const applyTransformers = (transformers: Function[]) => (response: any) => { ...

Guide to generating TypeScript output files within a non-hierarchical directory layout

In my project, I have a directory structure with multiple typescript files organized as follows: | src | app-1 | tsconfig.json | app-2 | tsconfig.json | common | standalone | tsconfig.json For each of the ...

Error message: Issue with AWS Serverless Lambda and Angular - TypeError: express function not defined

I'm encountering an issue when trying to deploy my application from localhost:4200 to AWS serverless Lambda. The error in cloudwatch logs is causing a 500 {"message": "Internal server error"} response when I access the URL. My understanding of AWS is ...

gulp-tsc cannot locate the src directory

I am currently working on developing a .NET Core application using Angular2, but I keep encountering the following error: /wwwroot/NodeLib/gulp-tsc/src/compiler.ts' not found. I'm having trouble pinpointing what I might be missing. tsconfig.js ...

Limit class generic to specify constructor argument type

I have a unique object that I need to transform into various structures based on its keys. Each key-value pair must be treated individually, so I intend to convert the object into an array of entries, then map those entries into policy objects and finally ...

Tips for successfully incorporating a date parameter in an Angular 8 GET request

Can anyone guide me on how to correctly pass a date in an Angular 8 $http Get request? I'm looking to achieve something like this: public getCalendarData(Date): any { let myResponse = this.http.get(`${environment.BASE_URL}/getCalendarData` + & ...