Creating a seamless integration between Angular 2's auth guard and observables to enhance application security

I'm having trouble setting up an auth guard for one of my routes because I am unsure how to implement it with an observable.

I am using ngrx/store to store my token. In the guard, I retrieve it using this.store.select('auth'), which returns an object like this (if the user is logged in):

{
  token: 'atokenstring',
  isAuthenticated: true,
  isPending: false
}

This is what the guard code looks like:

export class AuthGuardService implements CanActivate {

  constructor(private router: Router, private store: Store<IStore>) {}

  canActivate(): Observable<any> {

    return this.store.select('auth').let((state: Observable<IAuthStorage>) => state.filter((auth: IAuthStorage) => !auth.isPending && auth.isAuthenticated)).map(
      (auth: IAuthStorage) => {

        if (!auth.isAuthenticated) {
          return this.router.navigateByUrl('admin/login');
        }
        else {
          return true;
        }
      }
    );
  }
}

The issue seems to be that the guard is returning an observable instead of a boolean value, preventing the route from rendering even when the else block returns true.

How can I modify the guard to return a boolean value instead of an observable?

Answer №1

There used to be a requirement like this in the past, although I am not sure if it still applies.

  canActivate(): Observable<any> {

    return this.store.select('auth').let((state: Observable<IAuthStorage>) => state.filter((auth: IAuthStorage) => !auth.isPending && auth.isAuthenticated)).map(
      (auth: IAuthStorage) => {

        if (!auth.isAuthenticated) {
          return this.router.navigateByUrl('admin/login');
        }
        else {
          return true;
        }
      }
    ).first(); // <<<=== added
  }

This setup ensures that the router only waits for one event instead of waiting for the observable itself to complete.

First must be imported in order to be accessible.

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

What options are available for customizing the date and time format within ngx-mat-datetime-picker?

Currently, I am working with Angular7 and the ngx-mat-datetime-picker which is compatible. It is functioning as intended. I am looking to customize the format: Current Format: mm/dd/yyyy, hh:mm:ss Desired Format: yyyy-mm-dd hh:mm:ss At the moment, I am ...

Converting javascript html object lowercase

Is there a way to dynamically adjust the height of specific letters in my label? Right now, I am overriding the text for the elements: let element = document.getElementById('xxx') element.textContent = 'Label' I attempted using <sup ...

What is the proper way to use Object.entries with my specific type?

On my form, I have three fields (sku, sku_variation, name) that I want to use for creating a new product. I thought of converting the parsedData to unknown first, but it seems like a bad practice. export type TProduct = { id: string, sku: number ...

Passing dynamic values to nested components within an ngFor loop in Angular

I'm currently facing an issue with a child component inside a ngFor loop where I need to pass dynamic values. Here is what I have attempted so far, but it doesn't seem to be working as expected <div *ngFor="let item of clientOtherDetails& ...

Safeguarding user data across all components is facilitated by Angular 2

My Angular2 app uses OAuth2 with password grant type for authentication. I currently store the session token on sessionStorage, but I need to securely store additional data such as user roles. While I am aware that sessionStorage or localStorage can be ea ...

An error is thrown when a try/catch block is placed inside a closure

An issue arises when attempting to compile this simple try/catch block within a closure using TypeScript: type TryCatchFn = (args: any, context: any) => void; function try_catch(fn: TryCatchFn): TryCatchFn { return (args, context) => void { ...

Hover shows no response

I'm having trouble with my hover effect. I want an element to only be visible when hovered over, but it's not working as expected. I've considered replacing the i tag with an a, and have also tried using both display: none and display: bloc ...

Splitting Ngrx actions for individual items into multiple actions

I'm currently attempting to create an Ngrx effect that can retrieve posts from several users instead of just one. I have successfully implemented an effect that loads posts from a single user, and now I want to split the LoadUsersPosts effect into ind ...

When attempting to compile my Angular project using the command ng build --prod, I encountered a server error stating that the document

Everything was running smoothly when I was working on my local machine, but once I uploaded the files generated from ng build --prod to the server, a problem arose. Now, whenever I try to route via a button in my components, an error appears. When I clic ...

TypeScript's type inference feature functions well in scenario one but encounters an error in a different situation

I recently tried out TypeScript's type inference feature, where we don't specify variable types like number, string, or boolean and let TypeScript figure it out during initialization or assignment. However, I encountered some confusion in its be ...

Discovering the best approach to utilizing Font Awesome 6 with React

Required Packages "@fortawesome/fontawesome-svg-core": "^6.1.1", "@fortawesome/free-solid-svg-icons": "^6.1.1", "@fortawesome/react-fontawesome": "^0.1.18", "next": " ...

Typeahead functionality in Angular UI Bootstrap that uses object properties to search and display

I have a similar item (recreation of Map): $scope.vehicles = { 1:{id:1, model:'Coupe'}, 2:{id:2, model:'Truck'}, 3:{id:3, model:'Hatchback'} } I want to utilize the property values in typeahead of ui bootstrap (whil ...

Creating variables in Typescript

I'm puzzled by the variable declaration within an Angular component and I'd like to understand why we declare it in the following way: export class AppComponent { serverElements = []; newServerName = ''; newServerContent = &apos ...

Organizing validators within reactive forms in Angular

When creating a form in Angular, I have multiple fields that need validation. Below is the code I am using to create the form: requestForm = this.formBuilder.group({ requestorName: ['', [Validators.required]], requestorEmail: ['&apo ...

Is there a way to transfer ngClass logic from the template to the TypeScript file in Angular?

I am implementing dropdown filters for user selection in my Angular application. The logic for adding classes with ngClass is present in the template: <div [ngClass]="i > 2 && 'array-design'"> How can I transfer this ...

Running an ESNext file from the terminal: A step-by-step guide

Recently, I delved into the world of TypeScript and developed an SDK. Here's a snippet from my .tsconfig file that outlines some of the settings: { "compilerOptions": { "moduleResolution": "node", "experimentalDecorators": true, "module ...

What can cause a problem with the reduce function that populates an empty object with keys in TypeScript?

I've encountered an issue with a function that is meant to reduce an object. The problem lies in using the reduce method to assign the values of acc[key] as object[key], which is resulting in errors in the code. I am trying to avoid using any specific ...

What is causing the error message "Module '@reduxjs/toolkit' or its type declarations are not found" to appear?

Although I have a good understanding of React-Redux, I decided to delve into TypeScript for further practice. Following the recommended approach from the react-redux team, I created a new project using the TS template: "npx degit reduxjs/redux-templa ...

How can I send a value to an Angular element web component by clicking a button with JavaScript?

I want to update the value of an input in an Angular component by clicking on a button that is outside of the Angular Element. How can I achieve this in order to display the updated value in the UI? Sample HTML Code: <second-hello test="First Value"&g ...

Hybrid angularjs and angular application faces issues as deployURL is removed in angular version 13, causing unexpected disruptions

UPDATED 7/6/2023 after realizing the issue is related to the hybrid nature of my application, not just angular upgrading. I have a hybrid app with both Angular and AngularJS components. Currently, all client files are built into a /client/ directory, with ...