【问题标题】:Angular http post error: Cannot read property 'post' of undefinedAngular http post 错误:无法读取未定义的属性“post”
【发布时间】:2019-08-24 01:22:00
【问题描述】:

我正在尝试发出我的第一个 http POST 请求。我的 GET 请求工作正常(在同一个服务中),但是当我尝试发出 POST 请求时,我收到了错误

错误类型错误:无法读取未定义的属性“帖子” 在 ApiService.push../src/app/services/api.service.ts.ApiService.getTracsStartEvents (api.service.ts:57)

我在同一个文件中以与使用 GET 请求相同的方式使用它。我不明白为什么 POST 请求不起作用。我在语法上一定有问题。谁能指出我正确的方向?

import { Device } from '../shared/device';
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})

export class ApiService {
  TRACS_URL = '<REMOVED>';
  DELORME_LOCATE_URL = '<REMOVED>';

  apiKey = '<REMOVED>';
  getAllDeviceAPI = 'PApps_AircraftInfo';
  getDeviceByIMEIAPI = 'PApps_AircraftInfo/FindByIMEI/';
  getDeviceByTailNumberAPI = 'PApps_AircraftInfo/FindByTailNumber/';
  getDeviceByCallsignAPI = 'PApps_AircraftInfo/FindByCallsign/';
  getTracsStartEventsAPI = 'GetStartTrackEvents';

  constructor(private httpClient: HttpClient) {}

  public createDevice( device: Device ){}

  public updateDevice( device: Device ) {
    console.log('going to call API to update device: ', device)
  }

  public deleteDevice( device: Device ) {
    console.log('going to call API to delete device: ', device);
  }

  public getDeviceByIMEI( imei: string ) {
    return this.httpClient.get<Device[]>(`${this.TRACS_URL}/${this.getDeviceByIMEIAPI}/${imei}?apikey=${this.apiKey}`);
  }

  public getDeviceByTailNumber( tailNumber: string ) {
    return this.httpClient.get<Device[]>(`${this.TRACS_URL}/${this.getDeviceByTailNumberAPI}/${tailNumber}?apikey=${this.apiKey}`);
  }
  public getDeviceByCallsign( callsign: string ) {
    return this.httpClient.get<Device[]>(`${this.TRACS_URL}/${this.getDeviceByCallsignAPI}/${callsign}?    apikey=${this.apiKey}`);
  }
  public getAllDevices( url?: string ) {
    return this.httpClient.get<Device[]>(`${this.TRACS_URL}/${this.getAllDeviceAPI}?apikey=${this.apiKey}`);
  }

  public getTracsStartEvents( imeiList: string[] ) {
    console.log('imeiList: ', imeiList );
    const httpHeaders = new HttpHeaders({
        'x-api-key': 'Ra4GyPWuzU1PKDKdmHyyK4WlMKV7v3j4JQhaU7i8',
        'Content-Type': 'application/json-patch+json',
        'Cache-Control': 'no-cache',
    });
    let options = {
      headers: httpHeaders
    };
    return this.httpClient.post<any[]>    (`${this.DELORME_LOCATE_URL}/${this.getTracsStartEvents}`,
      {
        data: { arr_imei: imeiList,
                searchType: 'REALTIME',
              }
      }, options ).subscribe( res => {
        console.log('query result:', res );
      });
    }
}

这里是我调用 post 函数的地方(这是来自另一个获取位置更新的服务):

import { Injectable } from '@angular/core';
import { ApiService } from './api.service';

import { GeoJson } from '../shared/geo-json';

@Injectable({
  providedIn: 'root'
})

export class PositionUpdateService {
  positionUpdate: GeoJson;

  constructor(private apiService: ApiService,
              ) {
    this.positionUpdate = new GeoJson( 'Feature',
    {type: 'Point', coordinates: [-121.0, 37.5, 1000]} );
    //console.log('posUpdate: this.positionUpdate: ', this.positionUpdate );
 }

  getMissionStartEvents( devices ) {
    console.log('posUpdate svc, getMissionStartevents, imeis: ', devices);
    const events =  this.apiService.getTracsStartEvents( devices );
    console.log(events);
  }
}

一切从我的HomeComponent开始:

export class HomeComponent implements OnInit, OnChanges {
   constructor(public appSettingsService: AppSettingsService,
               public layerControlDialogComponent: MatDialog,
               private devicesToTrackService: DevicesToTrackService,
               private positionUpdateService: PositionUpdateService,
               private httpClient: HttpClient) { }
  startTracking(devices) {
     console.log('going to start tracking ', devices);
     this.positionUpdateService.getMissionStartEvents(devices)
  }

【问题讨论】:

  • 你怎么打电话给getTracsStartEvents
  • 我能看到的唯一带有post 的行是return this.httpClient.post,所以逻辑告诉我this.httpClient 是未定义的。检查您的代码或尝试在 stackblitz.com 上重现它,以便我们检查问题。
  • 但是我在上面的函数中使用了httpClient。这对我来说没有意义,为什么它会在两行之后未定义
  • 因为this 引用取决于函数的调用方式。您必须使用箭头函数而不是匿名函数(至少这是我的假设)。请在您调用getTracsStartEvents的地方添加代码sn-p@

标签: javascript angular typescript http dependency-injection


【解决方案1】:

确保将您的ApiService 注释为Injectable()

@Injectable({
  providedIn: 'root',
})
export class ApiService {

那么,不要自己创建ApiService,这就是依赖注入的目的。它将自动创建一个 ApiService 及其依赖项的实例(在本例中为 HttpClient):

export class PositionUpdateService {
  // The dependency injection will automatically instantiate ApiService
  constructor(private apiService: ApiService) {
   }

  // ...
}

【讨论】:

  • 它是可注射的。但是现在当我摆脱对象的创建时,我得到了一个不同的未定义错误 - 现在它返回 ERROR TypeError: Cannot read property 'getTracsStartEvents' of undefined
  • 可注入provideIn: 'root'?
  • 如何实例化PositionUpdateService?它也必须通过依赖注入来创建。
  • 那是神奇的按钮!我在 home 组件中手动实例化 UpdateService,这是问题的根本原因!谢谢!
  • 很高兴它现在为您工作。 :-) 我推荐阅读angular.io/guide/dependency-injection
【解决方案2】:

首先,http.get 和 http.post 返回 observables,wish 不会执行,除非你订阅它,像这样:

this.apiService.getTracsStartEvents(devices).subscribe()

其次,Angular 中的依赖注入不是这样工作的。

  1. 不要使用 new 关键字来实例化 apiService,直接使用它,就像使用 httpClient 一样,只需使用 this.apiService。

  2. 最后确定你提供了apiService,如果没有,把这个:

    @Injectable({providedIn: ‘root’})
    export class ApiService { ...
    

get 方法也不应该工作。如果您尝试订阅它,您将遇到相同的错误,可能是因为构造函数中的 apiService 实例化。

【讨论】:

    猜你喜欢
    • 2020-04-03
    • 2016-11-04
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 2023-01-15
    • 1970-01-01
    相关资源
    最近更新 更多