#angular #typescript
#angular #typescript
Вопрос:
Я пытаюсь настроить службу, которая будет выполнять Http get и возвращать данные JSON вызывающему. Я думаю, что у меня все настроено правильно на основе примеров, которые я использую, но компилятор не позволяет мне вызывать службу для получения данных. Сообщает мне, что я пытаюсь вызвать функцию void, но я явно возвращаю значение в этой функции. Вот код для службы:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class AircraftInfoService {
aircraft: string;
api = 'https://<notshow>/api/PApps_AircraftInfo?apikey=<notshown>';
constructor(private httpClient: HttpClient) {
}
ngOnInit() {
console.log('aircraftInfoservice');
}
getAircraft() {
this.httpClient.get(this.api).subscribe((res)=>{
console.log('aircraft: ', res );
return res;
})
}
}
И здесь я пытаюсь вызвать службу в app.compontent.ts:
export class AppComponent implements OnInit{
className: string;
isAuthenticated$: Observable<boolean>;
appSettings: AppSettings;
appSettingsSub: Subscription;
themeClass: string;
_wing: string;
_theme: string;
aircraftDB: string;
constructor(
private titleService: TitleService,
public appSettingsService: AppSettingsService,
private httpClient: HttpClient,
public aircraftInfoService: AircraftInfoService,
private matIconRegistry: MatIconRegistry,
private domSanitizer: DomSanitizer,
private adalService: AdalService,
private logger: LogService,
private overlayContainer: OverlayContainer,
@Inject(LOCAL_STORAGE) private storage: WebStorageService
){
adalService.init(environment.config);
this.matIconRegistry.addSvgIcon(
"historical-tracking-black-48",
this.domSanitizer.bypassSecurityTrustResourceUrl("../assets/historical-tracking-black-48.svg")
);
this.matIconRegistry.addSvgIcon(
"historical-tracking-black-48-inactive",
this.domSanitizer.bypassSecurityTrustResourceUrl("../assets/historical-tracking-black-48-inactive.svg")
);
}
ngOnInit(){
this.className = this.constructor.toString().match(/w /g)[1];
this.appSettings = this.appSettingsService.behaviorSubject.getValue();
this.appSettingsSub = this.appSettingsService.behaviorSubject.asObservable().subscribe(value => {
this.appSettings = value;
this._wing = this.appSettings.wing;
this.themeClass = this.appSettings.theme;
});
this.aircraftDB = this.aircraftInfoService.getAircraft();
this.adalService.handleWindowCallback();
this.logger.debug(this.className, "adal userInfo: ", this.adalService.userInfo);
}
Строка
this.aircraftDB = this.aircraftInfoService.getAircraft()
вызывает проблему:
Тип ‘void’ нельзя присвоить типу ‘string’
Что я делаю не так?
Спасибо
Ответ №1:
Этот метод вернет Subscription
первый. итак, вы получаете эту ошибку. Вы можете решить это двумя способами:
getAircraft() {
this.httpClient.get(this.api).subscribe((res)=>{
console.log('aircraft: ', res );
return res;
})
Измените тип aircraftDB
на any
aircraftDB: any
. Но это неправильный способ. Другой способ — вернуть подписку следующим образом:
getAircraft() {
return this.httpClient.get(this.api);
}
В вашем component.ts вы можете подписаться на него и назначить res
для this.aircraftDB
this.aircraftInfoService.getAircraft().subscribe((res)=>{
console.log('aircraft: ', res );
this.aircraftDB = res;
});
Ответ №2:
Вариант 1 Перейдите в свой сервис
getAircraft() {
this.httpClient.get(this.api).pipe(
map((res: any) => {
return res.toString();
})
);
}
Вариант 2
верните наблюдаемый объект из службы и подпишите его в свой AppComponnet
getAircraft() {
return this.httpClient.get(this.api);
}
и в AppComponent
this.aircraftInfoService.getAircraft().subscribe((res: any) {
console.log('Response', res);
});
Ответ №3:
Вопрос на первом месте why do you want to reference your service ?
. Если все, что вы хотите, это вызвать service
компонент in, все, что вы должны сделать в subscribe
для него. Потому что http
вызов является async
, т.е. you don't get the data right away... you have to make the requst and await the response
вот где Observable
появляется картинка.
Итак, хорошим решением является небольшое изменение реализации вашего сервиса, оно должно возвращать observable<datatype>
getAircraft():Observable<any[]> {
this.httpClient.get(this.api).subscribe((res)=>{
console.log('aircraft: ', res );
return res;
});
}
и затем в вашем, component
вам просто нужно subscribe
к нему
ngOnInit() {
...
this.aircraftInfoService.getAircraft().subscribe((data)=>{
this.aircraftDB = data;
});
...
}