В моем SPA я использую токен APP_INITIALIZER, который должен выполнить следующее в данной последовательности.1) Загрузите файл конфигурации, относящийся к среде (DEV, QA, PROD).2) Используйте URL-адрес API из файла конфигурации, чтобы сделать HTTP-запрос для токена аутентификации. 3) Используйте URL-адрес API из файла конфигурации и добавьте токен к HTTP-запросу (это происходит внутри перехватчика токена), чтобы загрузить некоторые другие конфигурации.data)
Раньше у меня были 2 и 3 реализованные с жестко запрограммированным URL, а затем все работало нормально.Когда я переместил URL-адреса API в конфигурацию и попытался загрузить их из файла конфигурации, конечная точка токена выполняется до того, как запрос файла конфигурации будет разрешен, поэтому 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, но не знаю, как к нему подойти.