What could be causing the interceptor to consistently return "null" as the value when using BehaviorSubject, instead of returning the updated value?

In the process of creating an authentication application utilizing the PEAN stack (PostgreSQL - ExpressJS - Angular - NodeJS).

To verify the user's sign-in status, the following steps are taken:

  1. On the backend, the session cookie is checked to determine the existence of the user property in the req.session object.

server.js

/* ... */

app.post('/api/get-signin-status', async (req, res) => {
  try {
    if (req.session.user) {
      return res.status(200).json({ message: 'User logged in' });
    } else {
      return res.status(400).json({ message: 'User logged out' });
    }
  } catch {
    return res.status(500).json({ message: 'Internal server error' });
  }
});

/* ... */
  1. Send an HTTP POST request to the api/get-signin-status endpoint along with a cookie in the request.

auth.service.ts

/* ... */

getSignInStatus(data?: any) {
  return this.http.post(this.authUrl + 'api/get-signin-status', data, {
    withCredentials: true,
  });
}

/* ... */
  1. Intercept any HTTP request and provide an observable interceptorResponse$ for subscribing to the response of intercepted requests.

interceptor.service.ts

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpEvent, HttpRequest, HttpHandler } from '@angular/common/http';
import { Observable, BehaviorSubject } from 'rxjs';
import { AuthService } from 'src/app/auth/services/auth.service';

@Injectable({
  providedIn: 'root',
})
export class InterceptorService implements HttpInterceptor {
  private interceptorResponse$: BehaviorSubject<any> = new BehaviorSubject<any>(null);

  intercept(httpRequest: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
   // code - omitted for brevity
  }

  getInterceptorResponse(): Observable<any> {
   // code - omitted for brevity
  }

  constructor(private authService: AuthService) {}
}
  1. On the frontend, subscribe to the interceptorResponse observable from the InterceptorService and log the response to the console.

header.component.ts

import { Component, OnInit } from '@angular/core';
import { InterceptorService } from '../auth/services/interceptor.service';

// code - omitted for brevity

  ngOnInit(): void {}
}

Issue

Following guidance from a StackOverflow answer, the use of BehaviorSubject is recommended. However, the implemented solution returns null instead of the expected updated value. By logging next and error, the expected user sign-in status is correctly displayed in the console.

Please refer to the images provided for further visual representation.

Query

Why does the Angular interceptor consistently return null with BehaviorSubject instead of the updated value?


UPDATE 1

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
// additional imports - omitted for brevity

UPDATE 2

The workaround to the quandary was successfully resolved with the assistance of @VonC. The adjustments made are detailed below.

  1. Elimination of the initial code in server.js as the interceptor now relies on the api/get-user endpoint, making the api/get-signin-status code superfluous. This update ensures that only one endpoint is needed for checking the session cookie, avoiding redundancy.

server.js

/* ... */

/* Removed code */
/* ... */
  1. Removal of the initial code in auth.service.ts and incorporation of the recommended modifications.

auth.service.ts

/* ... */

/* Removed code */
/* Added code */
  1. Revamp of the original code in interceptor.service.ts as advised by @VonC. The endpoint was updated to api/get-user for alignment with the backend logic.

interceptor.service.ts

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpEvent, HttpRequest, HttpHandler, HttpResponse } from '@angular/common/http';
// additional imports - omitted for brevity
  1. Modification of the initial code in header.component.ts to integrate the proposed changes.

header.component.ts

import { Component, OnInit } from '@angular/core';
import { AuthService } from 'src/app/auth/services/auth.service';
// additional imports - omitted for brevity

  ngOnInit(): void {}
}

The integration now allows for the presentation of elements in header.component.html based on the sign-in status retrieved from the backend.

header.component.html

<div *ngIf="signInStatus">Show this element if the user is signed in</div>
<div *ngIf="!signInStatus">Show this element if the user is signed out</div>

Answer №1

It seems like Angular might be generating multiple instances of your interceptorService, causing issues. One instance is likely being used as an interceptor, while another is being injected into your components/services.

I recall encountering a similar issue in the past, and my solution involved the following:

class HttpClientInterceptor {
    constructor(private readonly dataService: SharedDataService) {}
}

class AppComponent {
    constructor(private readonly dataService: SharedDataService) {}
}

Both the interceptor and component rely on a shared service to exchange data.

UPDATE

A quick search has confirmed this suspicion. You can refer to Interceptor creating two instances of a singleton service for more insights.

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

Encounter an error message stating "Request failed with status code 502 nginx in Next.js TypeScript."

After setting up Next.js typescript with Kubernetes NGINX Ingress, I encountered a problem where specific routes were returning a 502 error. For example, the route /test works fine, but /login does not. I'm unsure whether the issue lies with Kubernete ...

Refreshing the private route redirects the user to the login page

Currently, I am working on setting up a private route within my React app. I have integrated Redux and Redux-Toolkit (RTK) Query for handling state management and data fetching. The issue I am facing is that whenever I reload the private page, it redirects ...

Beneath the Surface: Exploring Visual Studio with NPM and Typescript

Can you explain how Visual Studio (2015) interacts with external tools such as NPM and the Typescript compiler (tsc.exe)? I imagine that during the building of a solution or project, MSBuild is prompted to execute these additional tools. I'm curious a ...

Guide on setting max-old-space-size in package.json for Node.js Express applications

I encountered a Javascript heap out of memory error recently. To address this issue, I decided to modify my package.json file as follows: "scripts": { "start": "node --max-old-space-size=4096 app.js && node ./bin/www" }, This was previou ...

Guide on accessing an element from a predicate object in Typescript while using Angular

I'm trying to wrap my head around how to access an element that exists on an object of a specific type but is defined as a type predicate. For example, let's say we have a Team defined as: let team$: Observable<ErrorModel | Team> The res ...

Using TypeScript to Extract Keys from an Array

Is it possible to mandate the keys of an interface to come from an array of strings: For instance, consider the following array: const myArray = ['key1', 'key2']; I aim to define a new interface named MyInterface that would require al ...

Angular 5 does not allow function calls within decorators

I encountered an issue while building a Progressive Web App (PWA) from my Angular application. When running ng build --prod, I received the following error: ERROR in app\app.module.ts(108,64): Error during template compile of 'AppModule' Fu ...

Acquiring an element through ViewChild() within Angular

I am in need of a table element that is located within a modal. Below is the HTML code for the modal and my attempt to access the data table, which is utilizing primeng. <ng-template #industryModal> <div class="modal-body"> <h4>{{&a ...

Node js - Looping Through Loading

I am facing an issue with my Node.js application. It runs perfectly fine on my local environment, but when I try to run it on my server using forever, the page just keeps loading without displaying anything. There seems to be no response and it gets stuc ...

What is the best method to retrieve the value of a cell in a different cell within the same row in an Angular Material Data-Table?

I am working with an Angular Material Data Table that has four columns. In every row, the last cell contains a button with an on-click function attached to it. I need to pass the value from the first cell ("Name") as a parameter in the corresponding button ...

Having trouble with querying subdocuments in MongoDB? Encountering issues like the error message "Converting

I am facing an issue with a document that contains an array of subdocuments: { "company": "example corp", "address": [ { "addr1": "25", "addr2": "", "addr3": "sample", "addr4": "", "addrcity": "", "addrcounty": ...

Error encountered when transitioning to TypeScript: Unable to resolve '@/styles/globals.css'

While experimenting with the boilerplate template, I encountered an unusual issue when attempting to use TypeScript with the default NextJS configuration. The problem arose when changing the file extension from .js to .tsx / .tsx. Various versions of NextJ ...

Exploring depths with Typescript recursion

I'm attempting to implement a recursive search in Typescript, but I am encountering an issue where TS is unable to determine the return type of the function. function findDirectory( directoryId: Key, directory: Directory, ) { if (!directory) ret ...

Building stateless functional components in React using Typescript version 0.14

Demonstration: import * as React from 'react' declare function obtainMarineLife(x: any): any; declare var Tank: any; var OceanicHabitat = ({category}) => ( <Tank> {obtainMarineLife(category)} </Tank> ); let y = <Ocea ...

Whenever the return condition is false, make sure to subscribe to the Angular CanActivate Guard

In my UserAccessGuard class, I have a method that captures the current path and compares it to the user's available paths. However, I am facing asynchronous problems because the condition inside the subscribe block causes my Hasaccess variable to rema ...

Having trouble with AES decryption on my nodeJS/ExpressJS server backend

Looking to decipher data post retrieval from mongoDb. The retrieved data comprises encrypted and unencrypted sections. app.get("/receive", async (req, res) => { try { const data = await UploadData.find(); const decryptedData = data. ...

What are the steps to configure Auth0 for an Angular application?

I'm having trouble implementing Auth0 into my angular app. After configuring it on [https://manage.auth0.com/dashboard/], clicking the save changes button results in this error: Error!Payload validation error: 'Object didn't pass validatio ...

Using Next.js, it is not possible to use absolute imports within SASS

Having trouble utilizing @/ imports within my scss files. The variables I need are stored in src/styles/_variables.scss Here is my tsconfig.json: { "compilerOptions": { "lib": ["dom", "dom.iterable", "esnext"], "baseUrl": ".", "allowJs": tr ...

Display unprocessed image data in the response

Currently, I am developing an API that generates authorized API calls to Google's APIs, specifically focusing on Google Drive. The API is functioning properly and utilizes Google's Node API for making requests. Upon sending a request to this reso ...

Tips for altering the hue of an inline svg within Angular?

I'm not very familiar with SVGs. Currently, I am using ng-inline-svg package to display inline SVG images. Is there a way to change the color of the SVG image? I've looked on stack overflow for solutions but haven't found anything that wor ...