#Why aren't the properties of my service loading?
10 messages · Page 1 of 1 (latest)
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
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
return this.graphService.getUserProfileImage(graphUser.userPrincipalName)
.pipe(
map((profileImage) => {
user.profileImage = profileImage;
return this.profile = user;
}),
catchError(_ => of(this.profile = user))
)