The Subscribe function in Angular's Auth Guard allows for dynamic authorization

Is there a way to check if a user has access by making an API call within an authentication guard in Angular? I'm not sure how to handle the asynchronous nature of the call and return a value based on its result.

The goal is to retrieve the user ID, use it to make an API request, and then return either true or false depending on the response from the API.

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from 'src/app/services/auth.service';

@Injectable({
  providedIn: 'root'
})
export class TeamcheckGuard implements CanActivate {
  success: boolean;

  constructor(
    private router: Router,
    private authService: AuthService
  ) {}

  // Checks to see if they are on a team for the current game they selected.
  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
      this.authService.getUserId().then(() => {
        let params = {
          gameId: next.params.id,
          userId: this.authService.userId
       };

        this.authService.getApi('api/team_check', params).subscribe(
          data => {
            if (data !== 1) {
              console.log('fail');
              // They don't have a team, lets redirect
              this.router.navigateByUrl('/teamlanding/' + next.params.id);
              return false;
            }
          }
        );
      });
    return true;
  }
}

Answer №1

To ensure secure access, you must provide an Observable<boolean> that resolves to either true or false based on the authentication request.

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    return new Observable<boolean>(obs => {
        this.authService.getUserId().then(() => {
            let params = {
                gameId: next.params.id,
                userId: this.authService.userId
            };

            this.authService.getApi('api/team_check', params).subscribe(
                data => {
                    if (data !== 1) {
                        console.log('fail');
                        // User does not have a team, so redirect them
                        this.router.navigateByUrl('/teamlanding/' + next.params.id);
                        obs.next(false);
                    }
                    else {
                        obs.next(true);
                    }
                }
            );
        });
    });
}

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

An issue has occurred: Unable to access the 'seatsavailable' property of an undefined object

Currently, I am immersed in a project involving Angular 6 and utilizing the @Input and @Output decorators. In this scenario, I have the Bookride Component functioning as the parent component with RideDetails serving as the child component. Successfully tra ...

Before users can apply any filters, all items must be loaded into an Observable<Hero[]> array

Is there a way to modify the Angular 2 Tour of Heroes search component so that it displays all items on page load (showing all Heroes) and then makes a new request to get filtered results only when a filter is provided? import { Component, OnInit } from & ...

What is the process for importing the TokenExpiredError that is thrown by the verify function in jsonwebtoken?

Is there a way to determine if an Error object thrown by the jwt.verify function in the jsonwebtoken library is of type TokenExpiredError using Typescript's instanceof? For example: import jwt from "jsonwebtoken"; function someFunction() { try { ...

Finding a solution for the network error encountered during the execution of XMLHttpRequest.send in the specified file path (...distfxcoreservermain.js:200

Having recently delved into Angular, I successfully completed the development of my angular web application. While using ng serve for production, everything ran smoothly. However, after incorporating angular universal and attempting npm run dev:ssr or np ...

Receiving undefined when subscribing data to an observable in Angular

Currently, I am facing an issue in my Angular project where subscribing the data to an observable is returning undefined. I have a service method in place that retrieves data from an HTTP request. public fetchData(): Observable<Data[]> { const url = ...

How to display placeholder text on multiple lines in Angular Material's mat form field

Within a standard mat-form-field, I have a textarea enclosed. However, the placeholder text for this Textarea is quite lengthy, leading to truncation with an ellipsis on mobile devices due to limited space. My goal is to adjust the placeholder text based ...

In the en-US locale, the toLocaleDateString function is transforming "00:30" into 24:30

Questioning the Conversion of Time from 00:30 to 24:30 in en-US Locale options = { year: "numeric", day: "numeric", month: "numeric", hour: '2-digit', minute: '2-digit&apo ...

Leveraging the spread operator in cases where the value is null

Is there a more elegant solution for handling null values in the spread operator without using if-else statements? In this specific case, I only want to spread assignedStudents if it is not undefined. When attempting to do this without using if-else, I e ...

Retrieve the total number of hours within a designated time frame that falls within a different time frame

Having a difficult time with this, let me present you with a scenario: A waiter at a restaurant earns $15/hour, but between 9:00 PM and 2:30 AM, he gets paid an additional $3/hour. I have the 'start' and 'end' of the shift as Date obje ...

Using JSON objects as values in Angular2

When displaying a select option in my HTML, I am currently able to show a string as the value. However, I would like to have the entire JSON object as the value instead of just the string that is being displayed. Here is my code: <select *ngIf="car" c ...

Angular Error: "Provider's ngAfterViewInit method is not defined at callProviderLifecycles"

I encountered an error: evt = TypeError: provider.ngAfterViewInit is not a function at callProviderLifecycles while working on my Angular project. What's strange is that I do not have an ngAfterViewInit method, nor do I have the corresponding impl ...

Triggering event within the componentDidUpdate lifecycle method

Here is the code snippet that I am working with: handleValidate = (value: string, e: React.ChangeEvent<HTMLTextAreaElement>) => { const { onValueChange } = this.props; const errorMessage = this.validateJsonSchema(value); if (errorMessage == null ...

What is a more efficient way to differentiate a group of interfaces using an object map instead of using a switch statement?

As someone still getting the hang of advanced typescript concepts, I appreciate your patience. In my various projects, I utilize objects to organize react components based on a shared prop (e.g _type). My goal is to automatically determine the correct com ...

"Creating a dynamic TreeList in Ignite UI by linking pairs of names and corresponding

I recently developed a drag and drop tree list inspired by the tutorial on IgniteUI website. The main tree list functions properly, but I encountered an issue with the child nodes displaying as undefined, as illustrated in the image below: https://i.sstat ...

Sending an array of data using Angular in a web service

Here is my model object from model.ts name_id: string[]; public generateUrlencodedParameters(token: string, id?: number): string { let urlSearchParams = new URLSearchParams(); urlSearchParams.append('name_id', this.name_id.toS ...

Combining one item from an Array Class into a new array using Typescript

I have an array class called DocumentItemSelection with the syntax: new Array<DocumentItemSelection>. My goal is to extract only the documentNumber class member and store it in another Array<string>, while keeping the same order intact. Is th ...

Identifying data types in arrays using TypeScript type predicates

My current approach involves a function that validates if a variable is an object and not null: function isRecord(input: any): input is Record<string, any> { return input !== null && typeof input === 'object'; } This type predica ...

Adding elements from one array to another array of a different type while also including an additional element (JavaScript/TypeScript)

I'm having trouble manipulating arrays of different types, specifically when working with interfaces. It's a simple issue, but I could use some help. Here are the two interfaces I'm using: export interface Group { gId: number; gName: st ...

Tips for showcasing with [displayWith] in Material2's AutoComplete feature

My API returns an array and I am using Material2#AutoComplete to filter it. While it is working, I am facing an issue where I need to display a different property instead of the currently binded value in the option element. I understand that I need to uti ...

What is the best way to pinpoint and eliminate a Subject from an Observable?

Currently, I am utilizing a service to gather user responses from a questionnaire. The sequence of events is outlined below: questionnaire.component.ts : serves as the main container that receives data from question.service.ts question-shell.component.ts ...