简体   繁体   English

角度:在APP_INITIALIZER中发送HTTP请求之前,加载配置文件

[英]Angular: Load config file before sending http request within the APP_INITIALIZER

In my SPA, I'm using the APP_INITIALIZER token, which is supposed to perform the following in the given sequence. 在我的SPA中,我正在使用APP_INITIALIZER令牌,该令牌应按照给定的顺序执行以下操作。 1) Load the config file relevant to the environment (DEV, QA, PROD). 1)加载与环境相关的配置文件(DEV,QA,PROD)。 2) Use the API URL from the config file to make the HTTP request for the authentication token 3) Use the API URL from the config file and append the token to the HTTP request (this happens within the token interceptor) to load some other config data) 2)使用配置文件中的API URL发出对身份验证令牌的HTTP请求3)使用配置文件中的API URL并将令牌附加到HTTP请求(这在令牌拦截器中发生)以加载其他配置数据)

Earlier I had 2 and 3 implemented with the URL hard-coded, and then everything worked fine. 之前我用硬编码的URL实现了2和3,然后一切正常。 When I moved the API Urls to the config and tried loading them from the config file, the token endpoint is executed before the config file request is resolved, therefore the url becomes undefined. 当我将API Urls移动到配置并尝试从配置文件加载它们时,令牌端点在配置文件请求得到解决之前就已执行,因此url变得不确定。

See the code below: 请参见下面的代码:

app.module.ts 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: 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 (token endpoint): 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);
        }
      );  
  }

Now, when I add breakpoints in app.config.ts and auth.service.ts, in the latter file, AppConfig.Settings.apiServer.tokenUrl get hit before the app config file is resolved. 现在,当我在app.config.ts和auth.service.ts中添加断点时,在后者文件中,AppConfig.Settings.apiServer.tokenUrl会在应用程序配置文件解析之前被命中。 Hence it becomes undefined. 因此,它变得不确定。

How can I resolve this? 我该如何解决? I know I should be using switchmap, but I'm not sure how to approach it. 我知道我应该使用switchmap,但是我不确定如何处理它。

Perhaps you can control the sequence in .then callback: 也许您可以控制.then回调中的顺序:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM