What prevents us from returning Observable.of(false) in the catch block within the canActivate function?

In order to protect certain routes (admin), I utilize the canActivate feature. In this scenario, I employ an authGuard class/function:

The issue arises when attempting to return an observable of boolean using: return Observable.of(false);. This approach does not yield the expected results and triggers the following Error:

Argument of type '(err: any) => Observable | Observable' is not assignable to parameter of type '(err: any, caught: Observable) => ObservableInput'. Type 'Observable | Observable' is not assignable to type 'ObservableInput'. Type 'Observable' is not assignable to type 'ArrayLike'. Property 'length' is missing in type 'Observable'.

Research on a similar issue was conducted, but the solutions found were not completely applicable. One suggested hint or solution recommended using .throw(err);

Upon switching the return statement to: return Observable.throw(err);, the error disappears. However, it fails to return false as required for route protection.

A potential root cause could be related to a type mismatch, yet attempts to rectify it have been unsuccessful while trying to maintain the use of observable.of(false).

canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean> | Promise<boolean> | boolean {
        return this.userService.getAdminAuth()
        .map( (res) => {
            if ( res === true) {
                return true;
            } else {
                ......
                return false;
            }
        })
        .catch( (err) => {
            if ( err.status === 403 ) {
                console.log(`403:  ${err.status}`);
                return this.userService.refreshToken()
                    .map( (res) => {
                        console.log(`Res RefreshToken: ${res}`);
                    });
            }
            return Observable.of(false); // protect route!
        });
}

Functions within user.service.ts:

....

isAdminAuthenticated = false;

public getAdminAuth() {
    console.log('Saved token: ' + localStorage.getItem('ac_token') );
    if ( this.isAdminAuthenticated === true ) {
        return Observable.of(true);
    } else {
        return this.http.get(
           'URL', { 
              headers: new HttpHeaders({"Accept": "application/json"}), 
              withCredentials: true, 
              observe: "response" 
           }
        )
        .map((res) => {
            if (res.status === 200) {
                this.isAdminAuthenticated = true;
                return true;
            } else {
                return false;
            }
        }, (err) => {
            console.log('Error: ' + err);
            return false;
        });
    }
}


refreshToken() {
    return this.http.get(
        'URL', 
        { 
            headers: new HttpHeaders(
                {
                    "Accept": "application/json",
                    "Authorization" : "Bearer " + localStorage.getItem('ac_token')
                }
            ), 
            withCredentials: true, 
            observe: "response" 
        }
    )
}

If the refreshToken function is modified to:

refreshToken() {
        return this._http.get(
            'URL', 
            { 
                headers: new HttpHeaders(
                    {
                        "Accept": "application/json",
                        "Authorization" : "Bearer " + localStorage.getItem('ac_token')
                    }
                ), 
                withCredentials: true, 
                observe: "response" 
            }
        ).map( (res) => {
            console.log(`Res: ${JSON.stringify(res)}` );
        }), (err) => {
            console.log(`Err: ${JSON.stringify(err)}` );
        };
}

An error message indicates:

ERROR in src/app/admin.guard.ts(38,9): error TS2322: Type 'Observable' is not assignable to type 'boolean | Promise | Observable'. Type 'Observable' is not assignable to type 'Observable'. Type 'boolean | {}' is not assignable to type 'boolean'. Type '{}' is not assignable to type 'boolean'. src/app/service.guard.ts: error TS2339: Property 'map' does not exist on type '(err: any) => boolean'.

Answer №1

It is recommended to utilize return Observable.throw(false) instead. The usage of of signifies success, whereas throw indicates an error.

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

The directive for accepting only numbers is not functioning in versions of Chrome 49.xx.xx and earlier

I have implemented a directive in Angular 6 to allow only numbers as input for certain fields. The directive code is shown below: import { Directive, ElementRef, HostListener } from '@angular/core'; @Directive({ selector: '[NumbersOnly]& ...

What steps do I need to take to ensure that the external API proxy for Angular 8 functions properly, without automatically defaulting to

In my current project, I'm attempting to set up a development Angular application to streamline the process of writing and testing services for our main NativeScript app in production. One of the challenges I've encountered is dealing with the C ...

I am experiencing an issue with my post method where I am not receiving any data back from the

I am using a POST method to send data to the server and I want to receive data back after that. When I subscribe to the post method: this.categoryService.storeCategory(this.currentFileUpload, this.category).subscribe(category => { console.log(" ...

Present information in a tabular format upon identifying an individual's ID using Angular

I encountered a specific issue recently. I successfully connected an API to my database using Angular, and it functions well by displaying all the data in a table. However, when I try to retrieve data for a single ID, the result can only be seen in an inpu ...

"Displaying the Material Input TextBox in a striking red color when an error occurs during

After referring to the links provided below, I successfully changed the color of a textbox to a darkish grey. Link 1 Link 2 ::ng-deep .mat-form-field-appearance-outline .mat-form-field-outline { color: #757575!important; } Although this solved the ...

Creating a personalized attribute directive within Angular2

I've been attempting to apply a custom attribute directive to an input element, but I'm struggling to achieve it. Here is my directive code: @Directive({ selector: '[disable-paste]' }) export class DisablePaste { constructor(p ...

Theme not being rendered properly following the generation of a dynamic component in Angular

I am currently working on an Angular 9 application and I have successfully implemented a print functionality by creating components dynamically. However, I have encountered an issue where the CSS properties defined in the print-report.component.scss file a ...

Getting to grips with the intricacies of the Gradle "task" syntax

I'm having trouble grasping the syntax of Gradle tasks. After following a tutorial, I created a build.gradle file for building Angular4/SpringBoots projects with Gradle. The build.gradle file includes several task blocks: // added our development b ...

Obtain a collection of lists stored in Firebase

As I work on creating an Ionic app with a Firebase database, my data structure in Firebase looks like the image below. I am utilizing angularfire2 to retrieve this data: https://i.stack.imgur.com/5akQf.png While I have successfully obtained the list of pa ...

Dealing with the Angular 7 ExpressionChangedAfterItHasBeenCheckedError in combination with NgsScrollReveal

Utilizing ngScrollReveal triggers a re-render with every scroll event. I am invoking a function through the HTML in this manner: <component [alternate]="toggleAlternate()"> The code for toggleAlternate() is as follows: toggleAlternate() { this.a ...

The Microsoft EDGE browser is encountering a XHR HTTP404 error when trying to access a TypeScript

While debugging a Typescript web application in Visual Studio 2015 and using the Microsoft EDGE browser, an error is reported as follows: HTTP404: NOT FOUND - The server cannot locate anything that matches the requested URI (Uniform Resource Identifier). ...

What are the circumstances under which JavaScript GCP libraries return null values?

My current project involves working with GCP and Firebase using typescript. I have been utilizing the provided libraries, specifically version 8 of Firebase, and have encountered some unexpected behavior. For instance (firebase, ver. 8.10.1) import 'f ...

Implementing a onClick event to change the color of individual icons in a group using Angular

I have integrated 6 icons into my Angular application. When a user clicks on an icon, I want the color of that specific icon to change from gray to red. Additionally, when another icon is clicked, the previously selected icon should revert back to gray whi ...

Tips for parsing data arrays in HTML templates

I have three variables and I created an array where I pushed all these three variables in. In my HTML template, I am using a table. I tried using *ngFor but it is not working, and also attempted string interpolation which also did not work. Currently, I ...

"Exploring Angular: A guide to scrolling to the bottom of a page with

I am trying to implement a scroll function that goes all the way to the bottom of a specific section within a div. I have attempted using scrollIntoView, but it only scrolls halfway down the page instead of to the designated section. .ts file @ViewChild(" ...

Is there a way to prevent the splash screen from appearing every time I navigate using a navbar link in a single page application (SPA)?

Recently, I came across this tutorial and followed it diligently. Everything seemed to be working perfectly until I encountered an issue with my navbar links. Each time I clicked on a link, the splash screen appeared, refreshing the page without directing ...

JS- Catching Errors Inside and Outside

Imagine having 2 catch blocks in your code: try { axios.get('https://example.com', {}) .then(function (responseOne: any) { return axios.post('https://example.com', {}, {}) }).then(async function (responseTwo: any) { return a ...

Strategies for preventing focus from shifting to tabbable elements within a chat component that has been minimized

There is a chat feature in my website that appears in a sidebar when the chat icon on the site header is clicked. To improve accessibility, I added tabindex = 0 to key elements such as the minimize and close icons on the chat container, as well as all th ...

Consider pushing items onto an array only once when the condition is met, instead of adding to the array every

I have been tasked with importing Excel files containing customer orders into my web application. The process involves converting the data in the file into an object of arrays, where each array represents a row from the Excel sheet. Once the data is impor ...

Incorporate JavaScript Library into StencilJs Using TypeScript

Recently, I decided to incorporate a JavaScript library called Particles.js into my project. The process involved importing it and initializing it within my component: import { Component, h } from '@stencil/core'; import * as particlesJS from &a ...