Angular ngOnInit 有问题
Trouble with Angular ngOnInit
我有一个从离开我们组织的人那里继承的应用程序。
我遇到了 ngOnInit 没有按照我认为应该的方式工作的问题。
我对使用 Angular 和 Observables
还是很陌生
当我导航到它进入 ngOnInit 方法的组件时,我可以在控制台中看到,我没有看到订阅中正在执行的响应的 console.info 语句。
进入组件后,我可以刷新页面,然后我可以在订阅中看到 console.info 语句。
我的问题是为什么我第一次导航到组件时没有看到 console.info 语句?
组件 ngOnInit() 方法
ngOnInit(): void {
console.info('Entering ngOnInit - Home Component');
this.profile.getProfile().subscribe((resp) => {
this.currentUser = this.local.getObject(StorageItems.UserProfile) as IMSALUserProfile;
console.info('Current User: ', + JSON.stringify(this.currentUserInit));
});
}
这就是我的服务的样子,它是一种使用 MSAL 从 Azure Active Directory 获取用户配置文件信息的服务。
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BaseService } from './base.service';
import { AuthError } from '@azure/msal-browser';
import { LoggerService } from './logger.service';
import { Observable, of } from 'rxjs';
import { IMSALUserProfile } from '../../shared/interfaces/msaluserprofile';
import { SessionService } from './session.service';
import { StorageItems } from '../../shared/interfaces/enums/storage.model';
import { LocalStorageService } from './local-storage.service';
import { UserService } from './user.service';
import { IUserInit } from '../../shared/interfaces/userinit';
@Injectable({
providedIn: 'root'
})
export class UserProfileService extends BaseService {
currentUser!: IMSALUserProfile;
currentUserInit!: IUserInit;
constructor(private http: HttpClient,
private logger: LoggerService,
private session: SessionService,
private local: LocalStorageService,
private userInit: UserService) {
super();
}
public getProfile(): Observable<IMSALUserProfile> {
let sessionUser = this.session.getItem(StorageItems.UserProfile);
if (sessionUser.length !== 0) {
this.currentUser = JSON.parse(this.session.getItem(StorageItems.UserProfile));
}
let profile!: IMSALUserProfile;
if (this.currentUser) {
profile = this.currentUser as IMSALUserProfile;
} else {
this.http.get('https://graph.microsoft.com/v1.0/me')
.subscribe({
next: (profile) => {
profile = profile;
this.local.setItem(StorageItems.UserProfile, profile);
this.session.setItem(StorageItems.UserProfile, JSON.stringify(profile));
this.currentUser = profile as IMSALUserProfile;
},
error: (err: AuthError) => {
console.info('Authentication error');
}
})
}
this.local.setItem(StorageItems.UserProfile, profile);
this.session.setItem(StorageItems.UserProfile, JSON.stringify(profile));
return of(profile);
}
}
当配置文件未定义时,您正在 returning of(profile)
。如果 this.currentUser
不存在,并且执行了 else
块,则您正在尝试异步设置 return 值。 http.get 之前的函数 return 可能会完成。
而不是订阅服务,您可能想要 return http 请求并通过一些 RxJS 运算符将其通过管道传输,以执行您当前在 else 块内的订阅中执行的任何逻辑。
我有一个从离开我们组织的人那里继承的应用程序。 我遇到了 ngOnInit 没有按照我认为应该的方式工作的问题。 我对使用 Angular 和 Observables
还是很陌生当我导航到它进入 ngOnInit 方法的组件时,我可以在控制台中看到,我没有看到订阅中正在执行的响应的 console.info 语句。 进入组件后,我可以刷新页面,然后我可以在订阅中看到 console.info 语句。
我的问题是为什么我第一次导航到组件时没有看到 console.info 语句?
组件 ngOnInit() 方法
ngOnInit(): void {
console.info('Entering ngOnInit - Home Component');
this.profile.getProfile().subscribe((resp) => {
this.currentUser = this.local.getObject(StorageItems.UserProfile) as IMSALUserProfile;
console.info('Current User: ', + JSON.stringify(this.currentUserInit));
});
}
这就是我的服务的样子,它是一种使用 MSAL 从 Azure Active Directory 获取用户配置文件信息的服务。
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BaseService } from './base.service';
import { AuthError } from '@azure/msal-browser';
import { LoggerService } from './logger.service';
import { Observable, of } from 'rxjs';
import { IMSALUserProfile } from '../../shared/interfaces/msaluserprofile';
import { SessionService } from './session.service';
import { StorageItems } from '../../shared/interfaces/enums/storage.model';
import { LocalStorageService } from './local-storage.service';
import { UserService } from './user.service';
import { IUserInit } from '../../shared/interfaces/userinit';
@Injectable({
providedIn: 'root'
})
export class UserProfileService extends BaseService {
currentUser!: IMSALUserProfile;
currentUserInit!: IUserInit;
constructor(private http: HttpClient,
private logger: LoggerService,
private session: SessionService,
private local: LocalStorageService,
private userInit: UserService) {
super();
}
public getProfile(): Observable<IMSALUserProfile> {
let sessionUser = this.session.getItem(StorageItems.UserProfile);
if (sessionUser.length !== 0) {
this.currentUser = JSON.parse(this.session.getItem(StorageItems.UserProfile));
}
let profile!: IMSALUserProfile;
if (this.currentUser) {
profile = this.currentUser as IMSALUserProfile;
} else {
this.http.get('https://graph.microsoft.com/v1.0/me')
.subscribe({
next: (profile) => {
profile = profile;
this.local.setItem(StorageItems.UserProfile, profile);
this.session.setItem(StorageItems.UserProfile, JSON.stringify(profile));
this.currentUser = profile as IMSALUserProfile;
},
error: (err: AuthError) => {
console.info('Authentication error');
}
})
}
this.local.setItem(StorageItems.UserProfile, profile);
this.session.setItem(StorageItems.UserProfile, JSON.stringify(profile));
return of(profile);
}
}
当配置文件未定义时,您正在 returning of(profile)
。如果 this.currentUser
不存在,并且执行了 else
块,则您正在尝试异步设置 return 值。 http.get 之前的函数 return 可能会完成。
而不是订阅服务,您可能想要 return http 请求并通过一些 RxJS 运算符将其通过管道传输,以执行您当前在 else 块内的订阅中执行的任何逻辑。