#Why aren't the properties of my service loading?

10 messages · Page 1 of 1 (latest)

paper reef
#

From my understanding, the app component should load the profile into the service, then the properties scoped within that service should be accessible from within the child components, but when I try to access the perspective, it's undefined.

#

user.service.ts

import { Injectable } from '@angular/core';
import { AccountInfo } from '@azure/msal-browser';
import { catchError, map, mergeMap, Observable, of } from 'rxjs';
import { GraphUser } from '../graph/graph.models';
import { GraphService } from '../graph/graph.service';
import { User } from './user.models';

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

  public identity?: AccountInfo;
  public profile?: User;

  constructor(private graphService: GraphService) { }

  /**
   * Sets the identity of the signed in user
   * @param accounInfo An instance of AccountInfo from the MsalService
   * @returns An instance of the identity of the signed in user
   */
  public setIdentity(accounInfo: AccountInfo): AccountInfo {
    return this.identity = accounInfo;
  }

  /**
   * Sign the user in and map all custom properties to their identity
   * @param userPrincipalName The unique identifier associated with the user; most commonly the email address
   * @returns A reference to the signed in user with all custom properties included
   */
  public setProfile(userPrincipalName: string): Observable<User> {
    return this.graphService.getUser(userPrincipalName).pipe(
      mergeMap((graphUser: GraphUser) => {
        let user: User = graphUser;
        user.initials = this.getInitials(user);

        // TODO: Remove he hardcoding here once connected to remote data source
        user.investmentTeams = [ OMITTED FOR BREVITY ].map((record) => {
          return {
            id: record.Id,
            name: record.Name,
            groupName: record.Group
          }
        });

        user.perspectives = [ OMITTED FOR BREVITY ].map((record) => {
          return {
            id: record.Id,
            name: record.Name,
            investmentTeams: user.investmentTeams
          }
        });

        user.investmentTeam = user.investmentTeams[0];
        user.perspective = user.perspectives[0];

        return this.graphService.getUserProfileImage(graphUser.userPrincipalName)
          .pipe(
            map((profileImage) => {
              user.profileImage = profileImage;
              return user;
            }),
            catchError(_ => of(user))
          )
      })
    );
  }

  /**
   * Generates initials for a given user
   * @param graphUser A reference to a user returned from Microsoft Graph
   * @returns Initials for the specified user
   */
  private getInitials(graphUser: GraphUser): string {
    return graphUser.displayName
      .split(/[\s,]+/)
      .map(chunk => chunk[0])
      .join('')
      .toUpperCase();
  }

}
#

app.component.ts

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  providers: [],
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent implements OnInit {
  private readonly _destroying$ = new Subject<void>();

  constructor(
    private broadcastService: MsalBroadcastService,
    private msalService: MsalService,
    public userService: UserService
  ) {
    this.broadcastService.inProgress$.pipe(
      filter((status: InteractionStatus) => status === InteractionStatus.None),
      takeUntil(this._destroying$)
    ).subscribe(() => this.refreshAuthUser());
  }

  private refreshAuthUser(): void {
    let activeAccount = this.msalService.instance.getActiveAccount();

    console.log(activeAccount);

    if (!activeAccount && this.msalService.instance.getAllAccounts().length > 0) {
      let accounts = this.msalService.instance.getAllAccounts();
      activeAccount = accounts[0];
      this.msalService.instance.setActiveAccount(activeAccount);
    }

    if (!activeAccount) {
      console.log("Failed to sign in the user.");
      return;
    }

    this.userService.setIdentity(activeAccount);
    this.userService.setProfile(activeAccount.username).subscribe((user) => {
      console.log(user);
      this.authUser = user;
    });
  }

  public ngOnDestroy(): void {
    this._destroying$.next(undefined);
    this._destroying$.complete();
  }

}
#

view-company.component.ts

@Component({
  selector: 'app-view-company',
  templateUrl: './view-company.component.html',
  styleUrls: ['./view-company.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class ViewCompanyComponent implements OnInit, OnDestroy {
  public perspective: Perspective;

  constructor(
    private userService: UserService
  ) {
    this.perspective = this.userService.profile!.perspective!;
  }

}
#

I feel like I'm losing my mind

charred scaffold
#

Well, unless I'm missing something, the profile property of the service, that you're reading in the child component, is never initialized anywhere in the code

paper reef
#

oh

#

my

#

god

paper reef