"An issue of type TypeError occurred: When logging out of the application, it appears that 'x is null

Currently in my app, I am working on implementing authentication following the guidance provided in this example: Click here for more information. However, I have encountered an error that reads "ERROR TypeError: 'x is null'" when trying to execute the logout function. Can anyone offer insight into what might be causing this issue and suggest potential solutions? Your guidance would be greatly appreciated.

One specific challenge I am facing is utilizing the isCurrentUserAdmin method across multiple components to determine whether the user has admin privileges or not.

Here is a snippet from the authenticationService.ts file:

private userSubject: BehaviorSubject<User>;
public user: Observable<User>;

 isCurrentUserAdmin(): boolean {
    this.user.subscribe(x => this.currentUserRole = x.role);
    return this.user && this.currentUserRole === Role.admin;
  }


  logout() {
    // Remove user from local storage to log them out
    this.deleteToken();
    this.userSubject.next(null);
    this.router.navigate(['/login']);
  }

Answer №1

checkIfUserIsAdmin(): boolean {
    this.user.subscribe(data => this.currentUserRole = data ? data.role : null);
    return this.user && this.currentUserRole === Role.admin;
}

Once the user logs out, their data becomes null
which means that accessing data.role will result in an error.

In addition, following @Gunnar B.'s suggestion to filter it may not be ideal
as the currentUserRole needs to be updated with the latest User information.
Otherwise, after logging out, the previous User's role will still persist.

Answer №2

A null is sent to the userSubject (which the user will receive as well). When trying to access a property of user in the isCurrentUserAdmin function, it results in an error because at that point user === null and no longer has the property (role).

To solve this issue, filtering out null-users is necessary (and it is advisable not to subscribe within that function to avoid creating multiple subscriptions every time the function is called).

this.user.pipe(filter(x => x !== null)).subscribe(x => this.currentUserRole = x.role);

It is important to place the subscription in a location where it is only executed once. Also, remember to unsubscribe when the component is destroyed. Although in this case, since the observable is within the same component and would be destroyed accordingly (I believe), unsubscribing may not be necessary but it is a good practice.

Edit:
In reality, you should consider unsubscribing when the user is set to null because technically there could still be a role even if the user is null. (This is prevented in the return with this.user, but it is somewhat flawed logic.)
If you subscribe when a user is set and unsubscribe when it is cleared, then the filter may not be needed.

Edit2:
Regarding performance concerns (depending on the frequency of function calls), you can also directly extract the role from the user observable:

return this.user.pipe(take(1)).subscribe(x => x ? x.role : null);

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 issue with React Redux and Typescript involving the AnyAction error while working on implementing

While integrating redux-persist into my React project, I encountered an error. Previously, Redux was working smoothly, but upon the addition of redux-persist, I started receiving this error message: Types of property 'dispatch' are incompatib ...

Creating a nrwl/nx workspace with Angular Universal and encountering a typing problem in Cypress configuration

TL;DR When I run yarn webpack:server, I encounter the error message Cannot find name 'cy'. Example repository: Branch displaying error Error Explanation Hello, I am currently in the process of setting up a minimal viable product project to ...

Working with Angular forms: Adding an element to a specific index in a

addStop() { const control = <FormArray>this.editForm.controls['stops']; control.push(this.initStop()); } I have a function that adds a new "stop" to the form array. However, I would like to add the new "stop" one position before th ...

AngularJS 2: Updating variable in parent component using Router

My current app.component looks like the following: import { Component, Input } from '@angular/core'; import {AuthTokenService} from './auth-token.service'; @Component({ selector: 'app-root', templateUrl: './app ...

Is it possible to change the value of a react-final-form Field component using the onSelect function?

I am currently working on a React application using TypeScript and incorporating the Google Places and Geocoder APIs through various React libraries such as "react-places-autocomplete": "^7.2.1" and "react-final-form": "^6.3.0". The issue I'm facing ...

Troubleshooting Ionic 4 IonSlides slideTo and getActiveIndex functionalities encountering issues within IonTab context

I am encountering an issue with my ion slides setup on a page. Here is the code snippet: <ion-slides #schemasliderref [options]="schemaSliderOpts" (ionSlideDidChange)="slideChange()"> <ion-slide *ngFor="let schemaImage of schemaImages; let i ...

Encountered an issue with Angular while trying to import scss variables: Module parse failed due to an unexpected token at

Our project previously utilized a palette for importing styles, which functioned correctly in Angular 13. However, upon upgrading to Angular 14, the palette no longer works as expected. Below are the specific details of the issue: Error: Module parse faile ...

Tips for sending a timestamp as input to a stored procedure in TypeScript with the mssql module

Currently, I am utilizing the mssql npm package to communicate with SQL server. I have encountered a dilemma where the variable (which is of type TIMESTAMP in sql server) fetched from a stored procedure is returned as a byte array. Now, I need to pass this ...

When logging off from an Angular2 application, the OIDC-client does not properly clear the cookies for the MVC application

I currently have an authorization server that is being used by both my Angular2 app and MVC webapp. In my Angular2 app, I've implemented authorization using the oidc-client JavaScript package. Everything works well except for the logout functionality ...

Guidelines on launching an ionic 4 modal using routes

How can I open a modal using routes? I attempted the following approach, but it did not work as expected: ngOnInit() { this.launchModal(); } async launchModal() { const modal = await this.modalController.create({ component: AuthPasswordR ...

Tips for maintaining the selection when switching pages with smart-table?

I have implemented smart-table in my project to allow users to select records from different pages and view them in a preview section. However, I am facing an issue where the selection made on the first page does not persist when navigating back to it aft ...

In order to emphasize the chosen list item following a component refresh

SCENARIO: Let's consider a scenario where I have a component named list, responsible for displaying a list of all customers. Within this list, certain conditions are set up as follows: 1) Initially, the 1st list-item (e.g. Customer 1) is selected by ...

The Angular-Slickgrid filter doesn't seem to be functioning properly. However, when the entire text is entered

Currently, I am utilizing angular-slickgrid for my project and I am trying to enable the filter functionality. Below is the code snippet: prepareGrid() { this.columnDefinitions = [ { id: 'title', filterable: true, name: 'Title', ...

Encountering a Typescript issue when linking a class component with the reducer

Within my class component that is linked to the redux rootReducer, I am encountering a TypeScript error specifically related to the mapPropsToState section. The error message reads: Property 'unit' does not exist on type 'DefaultRootState&ap ...

A guide on leveraging Jest and Typescript to mock a static field within a class

While working with Typescript and a third-party library, I encountered an issue trying to write unit tests that mock out the library. Here's an example scenario: // Library.ts // Simulating a third party library export class Library { static code ...

I require the ability to modify cellEditor parameters in real-time

How can a value be passed to cellEditorParams after the user double clicks on a grid row? The application triggers a service call on row click and the response needs to be sent to cellEditorParams. ...

Is there a way to remove the sign up link from the AWS Amplify Vue authenticator?

Utilizing the amplify-authenticator component from the aws-amplify-vue library to manage authentication in my application. I am currently exploring methods to disable the "Create Account" link on the front end interface, but haven't found a direct sol ...

The click event was not captured by the Angular innerhtml element

<div style="text-align: left;margin-left: 10px;flex-grow: 1;"> <div [innerHtml]="secureHtml(control.data.text)" *ngIf="mode!=Mode.MODE_EDITABLE" (click)="handleClick()"></div> ...

The error property is not found in the type AxiosResponse<any, any> or { error: AxiosError<unknown, any>; }

As a beginner with typescript, I am encountering some issues with the following code snippet import axios, { AxiosResponse, AxiosError } from 'axios'; const get = async () => { const url = 'https://example.com'; const reques ...

Exploring the potential of utilizing arguments within the RxJS/map operator

When working with rxjs, export function map<T, R, A>(project: (this: A, value: T, index: number) => R, thisArg: A): OperatorFunction<T, R>; I seem to be struggling to find a practical use for thisArg: A. ...