Stop non-logged-in users from accessing page content rendering

Lazy loading is being used in my application to render pages.

{ path: 'dashboard', loadChildren: './dashboard/dashboard.module#DashboardModule', canActivate: [AuthGuard] }

The problem arises when the user types www.mydomain.com/dashboard in the URL. The browser ends up rendering the dashboard page momentarily before redirecting to the login screen. How can I prevent any page from being rendered if the user is not logged in, and instead directly redirect them to the login page?

AuthGuard Class

export class AuthGuard implements CanActivate {

  result: boolean = false;
  auth: any;
  outRes: any;


  constructor(private _authService: JwtService, private _router: Router) {

  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {

    this.outRes = this._authService.isAuthenticated();

    if (this.outRes) {
      this.outRes.subscribe(o => o ? true : this._authService.redirectToLogin());

      return true; 
    } else {

      this._authService.redirectToLogin();
      return false;
    }

  }

}

Service Class

  public isAuthenticated() {

    if (!this.loggedIn)
      this.redirectToLogin();

    return this.httpClient.get<boolean>(`${this.settings.getApiSettings('uri')}/api/auth/IsTokenValid`, {
      params: { token: this.getToken }
    }).map( /// <<<=== use `map` here
      (response) => {

        if (response !== null) {

          var receivedToken = response["securityStamp"];
          var availableToken = localStorage.getItem('access_token');

           //Check if received a refreshed token. (tokens are refreshed every 15 minutes)
          if (receivedToken && receivedToken !== availableToken) {

            localStorage.removeItem('access_token');
            localStorage.setItem('access_token', response["securityStamp"]);

          }

        }

        let data = response;
        if (data == null)
          return false;
        else
          return true;

      }
    );

  }

  redirectToLogin() {

    localStorage.removeItem('access_token');
    window.location.href = "./login";

  }

Answer №1

The root of the problem lies in this section of your code: if (this.outRes) and also in this part:

o => o ? true : this._authService.redirectToLogin()
. In both cases, the result will always be true because your function will consistently return a response without ever being null; essentially, you are only checking for the existence of a response, but not its actual value (true or false).

 canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {

    let isAuth: any;
    this._authService.isAuthenticated()
       .subscribe(response => isAuth = response); //<== this can true or false based on service

    if (!isAuth) {
      this._authService.redirectToLogin();
    }
     return isAuth;
  }

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

Encountering an installation issue with Angular 2 data table

Is there a solution for resolving unmet peer dependencies during the installation of Angular 2 data table? Here is the issue I am encountering while trying to install it. https://i.sstatic.net/HcirY.png ...

Angular error TS2322 arises when attempting to assign a type of 'Observable<{}>' with the share() operator

Currently diving into Angular 5, I've been exploring the Observable/Observer pattern to facilitate event sharing and data changes among subscribers. Below is a snippet of the code in question: ... @Injectable() export class NidoService { ... eve ...

What is the best way to target changing elements displayed by *ngIf?

Trying to access a dynamic element generated by ngIf in the code below has proven to be challenging. I attempted two different methods: Using ElementRef and querySelector Component template: `<div class="test" *ngIf="expr"> <a id="b ...

Troubleshooting: Empty Rows displayed in PrimeNG Table

Experimenting with Angular 8 and the primeNG package, I'm facing an issue where I cannot retrieve values. Despite using the {{staff[col.field]}} syntax, I only get empty rows of data. However, when I utilize the interface definition like {{staff.Emplo ...

The application within the Main Module is not being acknowledged by the other components within the module

I am facing an issue with my AngularJS application where the directive I created within the 'FormTest' module is not recognizing the variable 'app' even though it is defined within the same module. The error message I receive is TS2304 ...

Arranging an array in Angular 7 with various states and numbers

Looking to tackle this array sorting issue in Angular 7, the data is fetched from the API: "Products": [ { "ProductCode": "MC30180", "Description": "Description_1", "NationalCode": "N.C. 0965", "Pend ...

Press the second form submit button after the completion of another Observable

Below is the unique process we aim to accomplish using solely RXJS Observables: Press Login button (form with username & password). We bind Observable.fromEvent with our form. Upon submitting the form, call loginUser() to send an http request to serv ...

The issue arises when the desired image size is not reflected correctly on the background after changing

I've been working on a basic image slideshow where the background image changes based on user selection. However, I've noticed that when I change the image for the first time, the backgroundSize: cover property seems to disappear. Even if I try c ...

Encountering Invalid Chai attribute: 'calledWith'

I am currently in the process of implementing unit tests for my express application. However, I encountered an error when running the test: import * as timestamp from './timestamp' import chai, { expect } from 'chai' import sinonChai f ...

Field that only permits numerical input without triggering events for other characters

I've encountered some issues with the default behavior of the HTML number input and I'm looking to create a simple input that only allows numbers. To address this, I have developed a directive as shown below: import { Directive, ElementRef, Hos ...

How can I retrieve the value of a promise in Promise.map?

I am currently working on a project that involves saving data to a database using Mongoose. One specific field in the database is the 'thumbnail' field, which needs to be filled with a base64 converted file after the file is uploaded to the serve ...

Dealing with a situation where different functions need to be called based on a condition while using unique button names. This is

<button type="button" class="btn btn-primary ms-4" (click)="update()">Save</button> <button type="button" class="btn btn-primary ms-4" (click)="create()">Add</button> B ...

Alter the value by clicking a button within the DynamicRadioGroupModel in ng Dynamic Forms

I am working with ng-dynamic-form (version 6.0.4) and NG Bootstrap in Angular 6. I have a simple question. When a button click event is triggered, I want to change the value in DynamicRadioGroupModel by using the "setValue()" method. However, I am facing ...

Tips for implementing react-hook-form in an Ionic Modal?

I've been experimenting with implementing react-hook-form in my Ionic React project. Here's a simple form I created: const CustomForm: React.FC<{ color: string }> = ({ color }) => { const { handleSubmit, register } = useForm(); con ...

Can observable data be saved into another observable data storage?

I attempted to retrieve the array of first names from the observable below, which receives its response from an API (hardcoded here). I aim to store the original data in a separate observable. Thus, my implementation is as follows: this.initialData = Obse ...

Angular version 7.2.1 encounters an ES6 class ReferenceError when attempting to access 'X' before it has been initialized

I have encountered an issue with my TypeScript class: export class Vehicule extends TrackableEntity { vehiculeId: number; constructor() { super(); return super.proxify(this); } } The target for my TypeScript in tsconfig.json is set to es6: ...

Why does the final value appear when passing an incrementing counter as a prop to multiple React Components created in a loop?

I am currently unraveling the concept of closures in JavaScript. Within this code snippet, I am cycling through the values of the 'items' array using a foreach loop. I have defined a let variable named "count" outside the scope of the loop. Afte ...

Issue with Angular Material: Default selection not being applied in mat-select component

When I have a mat-select with options defined as objects in an array, I am facing an issue where the default selected value is not being set when the page renders. In my TypeScript file, I have: public options2 = [ {"id": 1, "name": "a"}, {"id": 2 ...

Encountering a type-safety problem while attempting to add data to a table with Drizzle

My database schema is structured like so: export const Organization = pgTable( "Organization", { id: text("id").primaryKey().notNull(), name: text("name").notNull(), createdAt: timestamp("c ...

Can functions be stored and invoked within a dictionary in TypeScript?

Currently, I'm in the process of refactoring some code and had a question regarding the possibility of declaring and initializing a dictionary that contains factory functions, with each function being associated with an enumerator key. This setup woul ...