【问题标题】:Trouble with Angular ngOnInitAngular ngOnInit 的问题
【发布时间】:2021-05-13 12:14:44
【问题描述】:

我有一个从离开我们组织的人那里继承的应用程序。 我遇到了 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);
  }
}

【问题讨论】:

  • getProfile() 是一团糟。我建议你在那里放置一个调试器并使用它,那里可能有一个错误停止执行。您可以评论所有内容,只需return of({})。为了安全起见,还要在您的组件上评论 this.currentUser = ...。你会看到你的console.info 语句都可以工作。开始逐条取消注释并找到错误。在此期间,重构事物。尽快。
  • 只是为了确认,在 ngOnInit 中,如果我在 resp 上执行 console.info,则为这一行。 this.profile.getProfile().subscribe((resp) => { 我不应该看到调用配置文件服务的响应吗?

标签: javascript angular typescript msal


【解决方案1】:

当配置文件刚刚未定义时,您将返回 of(profile)。如果this.currentUser 不存在,并且else 块被执行,您正在尝试异步设置您的返回值。该函数可能在 http.get 完成之前返回。

您可能希望返回 http 请求并通过一些 RxJS 操作符将其通过管道传递给 else 块中的订阅,而不是订阅服务。

【讨论】:

  • 康纳,感谢您的指导。确实是服务中的某些内容无法正常工作。我现在可以工作了。
猜你喜欢
  • 1970-01-01
  • 2018-07-26
  • 2020-11-04
  • 2018-06-12
  • 1970-01-01
  • 1970-01-01
  • 2020-08-08
  • 2018-03-19
  • 2016-06-26
相关资源
最近更新 更多