【问题标题】:Angular: Load config file before sending http request within the APP_INITIALIZERAngular:在 APP_INITIALIZER 中发送 http 请求之前加载配置文件
【发布时间】:2019-05-08 10:48:52
【问题描述】:

在我的 SPA 中,我使用的是 APP_INITIALIZER 令牌,它应该按照给定的顺序执行以下操作。 1)加载与环境(DEV、QA、PROD)相关的配置文件。 2) 使用配置文件中的 API URL 对身份验证令牌发出 HTTP 请求 3) 使用配置文件中的 API URL 并将令牌附加到 HTTP 请求(这发生在令牌拦截器中)以加载其他一些配置数据)

之前我用硬编码的 URL 实现了 2 和 3,然后一切正常。当我将 API Urls 移动到配置并尝试从配置文件加载它们时,令牌端点在配置文件请求被解析之前执行,因此 url 变为未定义。

请看下面的代码:

app.module.ts

export function initializeData(appConfig: AppConfig, authService: AuthService, appService: AppService, globalService: GlobalService) {
  return () => {
    try {
      return Promise.all([appConfig.load(), authService.authenticateClient(), appService.getClientConfig()]).then(() => {
        console.log('success')
        return Promise.resolve();
      }, (err) => {
        alert(err.error.error_description);
        return Promise.reject(err);
      });
    } catch (e) {
      alert(e.message);
      console.log(e);
    }

  }
}

@NgModule({
.............
.............
providers: [
    AppConfig,
    AuthService,
    {
      provide: APP_INITIALIZER,
      useFactory: initializeData,
      deps: [AppConfig, AuthService, TranslateService, AppService, GlobalService],
      multi: true
    },
    AppService
]
});

app.config.ts:

@Injectable()
export class AppConfig {
  static settings: IAppConfig;
  constructor(private http: HttpClient) { }
  load() {
    const jsonFile = `assets/config/config.${environment.name}.json`;

    return new Promise((resolve, reject) => {
      this.http.get(jsonFile).pipe(map((res: IAppConfig) => {
        AppConfig.settings = <IAppConfig>res;
        return AppConfig.settings;
      })).subscribe(() => {
        resolve();
        })
    }).catch ((response: any) => {
        console.log(`Could not load file '${jsonFile}': ${JSON.stringify(response)}`);
      });
  }
}

auth.service.ts(令牌端点):

authenticateClient(){
    let body = new HttpParams()
      .set('client_id', AppConfig.settings.apiServer.client_id)
      .set('grant_type', AppConfig.settings.apiServer.grant_type)
      .set('scope', AppConfig.settings.apiServer.scope);

    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/x-www-form-urlencoded'
      })
    };

    let authGatewayUrl: string = AppConfig.settings.apiServer.tokenUrl + window.location.search;

    return  this.http.post<any>(authGatewayUrl, body, httpOptions).toPromise().then(
        data => {
          this.token.next(data); 
          return this.token;
        },
        error => {
          return Promise.reject(error);
        }
      );  
  }

现在,当我在 app.config.ts 和 auth.service.ts 中添加断点时,在后一个文件中,AppConfig.Settings.apiServer.tokenUrl 在应用配置文件被解析之前被命中。因此它变得未定义。

我该如何解决这个问题?我知道我应该使用 switchmap,但我不确定如何使用它。

【问题讨论】:

  • appConfig.load().then(()=>Promise.all[authService.authenticateClient(), appService.getClientConfig()].then....)?
  • 谢谢。我不应该错过的。请添加回复,以便我将其标记为答案。
  • 按你说的添加回复:)

标签: angular http promise


【解决方案1】:

或许你可以在 .then 回调中控制顺序:

appConfig.load()
  .then(()=>
     Promise.all[
       authService.authenticateClient(),
       appService.getClientConfig()
     ]
     .then....)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多