0
votes

So I have been at this for a while now and cannot figure out why I keep getting back an empty observable.

Service:

import { Injectable } from '@angular/core';
import { WebApiService } from './web-api-service';
import { BehaviorSubject, Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private currentUserName: Subject<any> = new BehaviorSubject<any>({});
  private currentUser: Subject<any> = new BehaviorSubject<any>({});

  constructor(private webApi: WebApiService) { }

  setCurrentUsername(username) {
    this.currentUserName.next(username);
  }

  setCurrentUser(user) {
    this.webApi.GetMenuItems(JSON.stringify(user)).subscribe(response => {
      if (response !== []) {
        let res = response.d.replace(/\n|\r/g, ""); //eliminate new line and return characters
        res = JSON.stringify(eval("(" + res + ")")); //convert string to valid json
        res = JSON.parse(res); //convert to javascript object
        this.currentUser.next(res); //store object
      }
    });
  }
  
  get username() {
    return this.currentUserName.asObservable();
  }

  get user() {
    return this.currentUser.asObservable();
  }
}

Home Component:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ColorGeneratorService } from '../../services/color-generator.service';
import { AuthService } from '../../services/auth.service';
import { Subscription } from 'rxjs';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-home-page',
  templateUrl: './home-page.component.html',
  styleUrls: ['./home-page.component.scss']
})
export class HomePageComponent implements OnInit, OnDestroy {

  user: Subscription;
  username: string ;

  roleArray: Array<any>

  constructor(private auth: AuthService, private route: ActivatedRoute) { }

  ngOnInit() {
    this.username = this.route.snapshot.paramMap.get('username');

    this.auth.setCurrentUsername(this.username);
    this.auth.setCurrentUser({ username: this.username });
    
    this.user = this.auth.user.subscribe(user => { 
      this.roleArray = user.roles;
    }); 
  }
}

Secondary Component:

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-subject-page',
  templateUrl: './subject-page.component.html',
  styleUrls: ['./subject-page.component.scss']
})
export class SubjectPageComponent implements OnInit {

  user: Subscription;
  username: string;

  constructor(private auth: AuthService) { }

  ngOnInit() {
    this.user = this.auth.user.subscribe(user => { 
      console.log(user);
    }); 
  }
}

So the Home Component "sets" the user in the auth service, and has a button that links to subject-page component. But once I click the button on the home page, and route to the subject-page component, the console.log in the subject-page component will return only an empty object {} as if the user was never set. Stackblitz example of the issue here

1
Who is responsible of providing username to your HomeComponent? I see the ngOnInit as the potential source of problems, since you're not subscribing to the URL parameters (you use snapshot), so if the username in URL is changed after init, you won't update it. And if HomeComponent is initialized before login, it will be nulls, hence you get your empty object. - Marc Sances
Try to subscribe to this.route instead of using snapshot and see if that helps with your issue. Here's an explanation on this issue: medium.com/@tiboprea/… - Marc Sances
Hi Marc, I tried what you suggested. However, the user does not change throughout the application, it is meant to be set once and persist. The Home Page Component does not have multiple routes. I created a stackblitz example of my issue and edited my original post. link - Mado

1 Answers

1
votes

I found that in my template file I was actually using standard <a href="/some-link">Click Me</a> instead of <a routerLink="/some-link">Click Me</a> This caused the page (and Angular app) to completely reload causing the value of the user observable to be reset to {}