Попытка извлечь Http JSON из службы angular

#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;
   });
  ...
}