typescript - Nhà máy dịch vụ khởi động Angular không bao giờ được gọi
Tôi có một dịch vụ khởi động mà tôi đang sử dụng trong ứng dụng Angular của mình. Dịch vụ này được sử dụng để gọi API REST của tôi và cung cấp địa chỉ URL cho người dùng.
Tôi có một tệp startup.service.ts, một tệp app.config.json và một tệp web.config như được hiển thị dưới đây:
//startup.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { catchError, map } from 'rxjs/operators';
import { Observable, throwError as _throw } from 'rxjs';
export interface Configuration {
api: string;
}
@Injectable()
export class StartupService {
constructor(private httpClient: HttpClient) {}
private _startupData: Configuration;
load(): Observable<Configuration> {
const data = this.httpClient.get<Configuration>('app.config.json').pipe(
map(config => config),
catchError((error: any) => _throw(error))
);
data.subscribe(d => {
this._startupData = d;
});
return data;
}
get startupData(): Configuration {
return this._startupData;
}
}
//app.config.json
{
"api": "http://localhost:64403/api/status"
}
//web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".json" />
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
<rewrite>
<rules>
<rule name="Angular routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/home/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Trong module ứng dụng của tôi, tôi đã thêm mã sau
//app.module.ts
export function startupServiceFactory(
startupService: StartupService
): Function {
return () => {
startupService.load();
};
}
const routes: Routes = [
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: '**', component: NotFoundComponent, pathMatch: 'full' }
];
@NgModule({
declarations: [AppComponent, HomeComponent, NotFoundComponent],
imports: [
BrowserModule,
CommonModule,
VehicleStatusModule,
FormsModule,
HttpClientModule,
HttpModule,
RouterModule.forRoot(routes),
LeafletModule.forRoot(),
StoreModule.forRoot(reducers),
EffectsModule.forRoot(effects),
StoreRouterConnectingModule
],
providers: [
StartupService,
{
// Provider for APP_INITIALIZER
provide: APP_INITIALIZER,
useFactory: startupServiceFactory,
deps: [StartupService],
multi: true
},
// router state composition
{ provide: RouterStateSerializer, useClass: CustomSerializer }
],
bootstrap: [AppComponent]
})
export class AppModule {}
Và mỗi khi tôi chạy ứng dụng, tôi nhận được lỗi sau,
TypeError: Không thể đọc thuộc tính 'api' của undefined
đến từ file app.service.ts của tôi. Nó nên trả về chuỗi: "http://localhost:64403/api/status"
//app.service.ts
@Injectable({ providedIn: 'root' })
export class VehicleService {
private API_URL = this.startupService.startupData.fleetApi;
constructor(
private http: HttpClient,
private messageService: MessageService,
private startupService: StartupService
) {}
Điều làm tôi còn bối rối hơn là việc này đã từng hoạt động vài ngày trước, nhưng sau khi tôi thêm cửa hàng NGRX của mình, nó đã ngừng hoạt động và cho tôi lỗi như trên. Việc gỡ lỗi của tôi cho thấy nhà máy dịch vụ khởi động không được gọi. Có ai biết tôi đã làm gì sai ở đây không? Xin hãy cho tôi biết nếu có bất kỳ điều gì mà bạn muốn tôi làm rõ.
Câu trả lời #1
Ngày xửa ngày xưa, tôi đã giải quyết tình huống tương tự này bằng cách sử dụng APP_INITIALIZER
https://angular.io/api/core/APP_INITIALIZER
https://devblog.dymel.pl/2017/10/17/angular-preload/
Câu trả lời #2
Một cách là thay đổi API_URL của bạn thành getter
private get API_URL () {
return this.startupService.startupData.fleetApi;
}
