The Observable.subscribe method does not get triggered upon calling the BehaviorSubject.next

In my Navbar component, I am attempting to determine whether the user is logged in or not so that I can enable/disable certain Navbar items. I have implemented a BehaviorSubject to multicast the data. The AuthenticationService class contains the BehaviorSubject object, as shown in the code snippet below:

import {Injectable} from '@angular/core';
import {Http, RequestOptions, Headers} from '@angular/http';
import {LocalStorage, SessionStorage} from "angular2-localstorage/WebStorage";
import {BehaviorSubject} from 'rxjs/BehaviorSubject';

import {Credentials} from './credentials';

@Injectable()
export class AuthenticationService {
    private _baseUrl="http://localhost:8080/webapi/authenticate/";
    private loggedIn: boolean;
    // Observable UserLoggedIn source
    private _userLoggedInBehavior = new BehaviorSubject<boolean>(false);
    // Observable UserLoggedIn stream
    userLoggedInBehaviorStream = this._userLoggedInBehavior.asObservable();

    constructor(private _http: Http){
         this.loggedIn = localStorage.getItem("authToken");
    }

    authenticate(credentials: Credentials){
        return this._http.post(
                            this._baseUrl
                            , JSON.stringify(credentials)
                            , this.getOptions()
                            )
                    .map(res => res.json())
                    .map((res) => {
                        if (res.success) {
                            sessionStorage.setItem("authToken", res.data.token);
                            this.loggedIn = true;
                        }
                        return res.success;
                    });
    }

    logout() {
        sessionStorage.removeItem("authToken");
        this.loggedIn = false;
    }

    isLoggedIn() {
        return this.loggedIn;
    }

    changeUserLoggedInBehavior(loggedIn) {
        this._userLoggedInBehavior.next(loggedIn);
    }

    getOptions(){
        var jsonHeader = new Headers({
            'Content-Type':'application/json'
        });
        var options = new RequestOptions({
            headers: jsonHeader
        });
        return options;
    }
}

The AuthenticationComponent triggers the authentication process, and its code looks like this:

    import {Component, OnInit, EventEmitter} from '@angular/core';
import {CanDeactivate, Router} from '@angular/router-deprecated';
import {ControlGroup, Control, Validators, FormBuilder} from '@angular/common';

import {AuthenticationService} from './authentication.service';
import {Credentials} from './credentials';
import {EmailValidator} from '../../validators/email-validator';

@Component({
    selector:'auth'
    , templateUrl:'app/components/authentication/authentication.component.html'
    , providers:[AuthenticationService]
})
export class AuthenticationComponent{
    form: ControlGroup;
    title: string = "LogIn";
    credentials: Credentials = new Credentials();

    constructor(
        fb: FormBuilder
        , private _authService: AuthenticationService
        , private _router: Router){

        this.form = fb.group({
            emailId:[
                ''
                , Validators.compose(
                        [
                            Validators.required
                            , EmailValidator.mustBeValidEmail
                        ]
                    )
                ]
            ,password:[
                ''
                , Validators.compose(
                        [
                            Validators.required
                        ]
                    )
            ]
        });
    }

    save(){
        this._authService.authenticate (this.credentials)
                .subscribe((result) => {
                    if (result) {
                        this._authService.changeUserLoggedInBehavior(true);
                        this._router.navigate(['Home']);
                    }
                }); 
    }
}

Lastly, the NavbarComponent code is as follows:

import {Component, OnInit, OnDestroy} from '@angular/core';
import {RouterLink} from '@angular/router-deprecated';
import {Subscription} from 'rxjs/Subscription';

import {AuthenticationService} from '../components/authentication/authentication.service';

@Component({
    selector:'navbar'
    , templateUrl: 'app/navbar/navbar.component.html'
    , directives:[RouterLink]
    , providers:[AuthenticationService]
})
export class NavbarComponent implements OnInit, OnDestroy{
    private _isUserLoggedIn: boolean=false;
    subscription: Subscription;
    constructor(
        private _authService: AuthenticationService
    ){}

    ngOnInit(){
        this.subscription = this._authService.userLoggedInBehaviorStream
                                .subscribe(
                                    loggedIn => this._isUserLoggedIn = loggedIn
                                    );
    }

    ngOnDestroy(){
        // prevent memory leak when component is destroyed
        this.subscription.unsubscribe();
    }

    public setUserLoggedId(isLoggedIn: boolean){
        this._isUserLoggedIn = isLoggedIn;
    }
}

I referred to an example on Stack Overflow to write this code (source). Please let me know if you see any issues with it.

Answer №1

Issue arises from how you're declaring the provider in both components:

providers:[AuthenticationService]

Whenever a service is provided in a component, a new instance is created each time. Consider providing AuthenticationService at a higher parent component level and then injecting it into child components or during bootstrapping.

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

Do not generate authentication code in JHipster using the --skip-server flag

Is there a reason why the authentication part is lost when generating a project with '--skip-server'? yo jhipster --skip-server It seems that upon generating the project without the server, the authentication gets affected (on AJS/A2). Is thi ...

What is the syntax for passing a generic type to an anonymous function in a TypeScript TSX file?

The issue lies with the function below, which is causing a failure within a .tsx file: export const enhanceComponent = <T>(Component: React.ComponentType<T>) => (props: any) => ( <customContext.Consumer> {addCustomData => ...

In React Typescript, there is an issue with react-router v4 where the Route component does not pass its props to the specified component

Struggling with React Router v4 and history usage in Browserrouter. Whenever attempting to access this.props.history.push("/"), the error pops up: TS2339: Property 'history' does not exist on type 'Readonly<{ children?: ReactNode; }> ...

Exclude<Typography, 'color'> is not functioning correctly

Take a look at this sample code snippet: import { Typography, TypographyProps } from '@material-ui/core'; import { palette, PaletteProps } from '@material-ui/system'; import styled from '@emotion/styled'; type TextProps = Omi ...

Disable inline imports when implementing an interface in vscode by selecting the "Implement interface" option

When using TypeScript, if I perform an auto-fix on a class name by selecting "Implement interface", it will generate the methods with inline imports like this: getInbox(): Observable<import('../../model/Message').Interactions[]> { t ...

CompositeAPI: Referencing HTML Object Template - Error TS2339 and TS2533 when using .value to access Proxy Object

Having trouble referencing an element in VueJS 3 CompositeAPI. In my current implementation, it looks like this: <div ref="myIdentifier"></div> setup() { const myIdentifier = ref(null); onMounted(() => { console.log(myIden ...

Error: Trying to access a property of an undefined variable (retrieving 'x')

As a newcomer to the MEAN stack, I am attempting to create some basic posts. However, I keep encountering an error that reads TypeError: Cannot read properties of undefined (reading 'title') when trying to issue a post. The strange thing is, when ...

An issue has occurred: TransformError SyntaxError: Unexpected keyword 'const' was encountered

While practicing programming with React-Native, I encountered a problem that I couldn't figure out how to solve. I attempted to use solutions from various forums, but none of them worked. import { StyleSheet, Text, View, Image } from 'react-nativ ...

Extracting a raw string from the parameters of ActivatedRoute in Angular 4

I've looked high and low for an answer to this, but couldn't find a solution. I'm passing a string in the URL like so: "localhost:4200/home/ABCD%2BrAD4Og%3D%3D". However, when I subscribe to the parameter or use snapshot, I get something dif ...

Typescript Error:TS2345: The argument '{ theme: string; jsonFile: string; output: string; }; }' is not compatible with the parameter type 'Options'

Encountering an error mentioned in the title while using the code snippet below: import * as fs from 'fs' import { mkdirp } from 'mkdirp' import * as report from 'cucumber-html-reporter' const Cucumber = require('cucumber ...

Allow Nest.js server to receive binary files in the request body

Is there a way to retrieve the uploaded binary file data from the browser? While the Nest.js server application functions correctly with Postman, it throws a 400 error when the request is sent from the Google Chrome/Angular application. Any ideas on how ...

Issue encountered with TypeORM and MySQL: Unable to delete or update a parent row due to a foreign key constraint failure

I have established an entity relationship between comments and posts with a _many-to-one_ connection. The technologies I am utilizing are typeorm and typegraphql Below is my post entity: @ObjectType() @Entity() export class Post extends BaseEntity { con ...

Modify one specific variable within my comprehensive collection on Firebase Firestore

After clicking the button, I need to update a variable. The variable in question is "bagAmount" and it is stored in my firestore collection. Here is a link to view the Firestore Collection: Firestore Collection Currently, I am able to update one of the va ...

How to implement the connect function in an Angular 2 table

Topic: Angular Material 2 implementation of md-table UI using cdk-table Problem: Unable to trigger connect method after a user-initiated HTTP call receives a response Approach: Create a hot observable from a behavior subject in a service. The parent c ...

Tips for configuring TypeScript in a monorepo to successfully compile private packages

I have configured a monorepo using turborepo that includes Nestjs for the backend and Nextjs for the frontend. To reuse prisma definitions, I separated them into their own package with its own tsconfig. In the index file of my database package where prism ...

Experimenting with throws using Jest

One of the functions I'm testing is shown below: export const createContext = async (context: any) => { const authContext = await AuthGQL(context) console.log(authContext) if(authContext.isAuth === false) throw 'UNAUTHORIZED' retu ...

How can I create interfaces for deeply nested objects in TypeScript?

Check out my current JSON data below: { "state_1": { "date": [ { 1000: { "size": 3, "count": 0 } }, { 1001: { "size" ...

Issue encountered in Loopback 4: Error with @repository dependency injection (TypeError: Undefined property 'findOne')

As I set up Bearer Token authentication for my Loopback 4 application, I referenced this implementation guide: https://github.com/strongloop/loopback-next/tree/master/packages/authentication. Within my src/providers/auth-strategy.provider.ts file, I encou ...

Tips for Passing On Parent tabindex Value to Children

Is there a way to propagate a parent's tabindex value to all of its children without individually setting tabindex for each child? Here is an example code snippet: <div id="app"> <div tabindex="2" class="parent-sec ...

Unlocking the Power of FusionAuth in NativeScript: A Guide

While attempting to utilize a library based on nativescript documentation, I encountered an issue where certain modules like net and tls were not being automatically discovered. After using npm install to include tls and net, the problem persisted with t ...