【问题标题】:Angular 4 HTTP Not Returning The JSON bodyAngular 4 HTTP 不返回 JSON 正文
【发布时间】:2018-02-08 01:16:45
【问题描述】:

我的 Typescript 中有以下方法!

allPowerPlants(onlyActive: boolean = false, page: number = 1): PowerPlant[] {
    const params: string = [
      `onlyActive=${onlyActive}`,
      `page=${page}`
    ].join('&');
    const path = `${this.allPowerPlantsURL}?${params}`;
    this.apiService.get(path).map(
      powerplants => {
        powerplants.map(item => {
          if (this.isPowerPlant(item)) {
            // make the item an instance of PowerPlant
            this.powerPlants.push(item as PowerPlant);
          }
      });
    },
    err => {
        console.log('oops **** some error happened');
      // handle error
    });
    console.log('powerplants obtained is *****************+ ');
    console.log(this.powerPlants);
    return this.powerPlants;
  }

我的 get 方法如下所示:

import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
import { Headers, Http, Response, URLSearchParams } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class ApiService {
  loading: boolean;
  data: Object;
  constructor(
    private http: Http,
  ) {}


    get(path: string, params: URLSearchParams = new URLSearchParams()): Observable<any> {
        console.log('sending request to ' + `${environment.api_url}${path}`);
        return this.http.get(`${environment.api_url}${path}`, { search: params })
          .catch(this.formatErrors)
          .map((res: Response) => {
            console.log('response as json is ' + res.json());
            res.json();
        });
      }
}

我的 isPowerPlant 方法如下所示:

isPowerPlant(item: any): item is PowerPlant {
    // check for the required properties of PowerPlant here and return true/false.
    // example:
    console.log('in the static method');
    const vvvv = item['maxPower'] && item['minPower'];
    console.log(vvvv);
    return vvvv;
  }

我期待在 console.log('response as json is ') 中看到一些数据,但奇怪的是它什么也没打印!请求甚至没有发送到服务器!

但是,当我将 allPowerPlants 方法更改为不映射到 get 方法时,而是像下面这样订阅:

this.apiService.get(path).subscribe(...)

我可以看到一些数据正在从服务器获取,正如我从服务器日志中看到的请求正在被处理一样。

我想做以下事情:

我希望 allPowerPlants 返回一个 PowerPlants 数组,定义如下:

export interface PowerPlant {
  powerPlantId: number;
  powerPlantName: string;
  minPower: number;
  maxPower: number;
  powerPlantType: string;
  rampRateInSeconds?: number;
  rampPowerRate?: number;
}

现在,由于我的 get 方法是一个 Observable,我看到我的 Angular 应用程序正在对服务器进行大量调用,这可以从我的服务器日志中看到:

[info] application - GET /powerPlants?onlyActive=false&page=1 took 3192ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2974ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2701ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2682ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2885ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2920ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2552ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2564ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2598ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2612ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2615ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2621ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2636ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2609ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2701ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2544ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2588ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2532ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2586ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2570ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2652ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2624ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2661ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2618ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2611ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2624ms HTTP status >> 200
[info] application - GET /powerPlants?onlyActive=false&page=1 took 2620ms HTTP status >> 200

这是我的服务器发送的实际数据:

[ {
  "powerPlantId" : 1,
  "powerPlantName" : "Organization-001",
  "minPower" : 20,
  "maxPower" : 100,
  "powerPlantType" : "OnOffType"
}, {
  "powerPlantId" : 2,
  "powerPlantName" : "Organization-001",
  "minPower" : 100,
  "maxPower" : 800,
  "rampPowerRate" : 100,
  "rampRateInSeconds" : 100,
  "powerPlantType" : "RampUpType"
}, {
  "powerPlantId" : 3,
  "powerPlantName" : "Organization-002",
  "minPower" : 200,
  "maxPower" : 400,
  "rampPowerRate" : 50,
  "rampRateInSeconds" : 50,
  "powerPlantType" : "RampUpType"
}, {
  "powerPlantId" : 4,
  "powerPlantName" : "Organization-002",
  "minPower" : 400,
  "maxPower" : 800,
  "powerPlantType" : "OnOffType"
} ]

如何让我的 allPowerPlants 只调用我的服务器一次,同时处理来自 get 方法的 Observable 结果?

这就是我在 HTML 中使用数据的方式:

<div class="ui grid posts">
  <app-powerplant
    *ngFor="let powerPlant of allPowerPlants()"
    [powerPlant]="powerPlant">
  </app-powerplant>
</div>

【问题讨论】:

  • 你从来没有说过 this.http 是什么......是新的 HttpClient 还是旧的 Http?
  • 我的帖子更新了!

标签: json angular http typescript observable


【解决方案1】:

这是从服务器调用数据的代码的 sn-p

this.apiService.get(path).map(
      powerplants => {
       ...
          }

停在那里。没有数据的原因是你没有订阅! 你应该这样做

this.apiService.get(path).subscribe(
      powerplants => {
        this.powerPlants = powerplants
        //remove the mapping. you can do it in your service.
    },
    err => {
        console.log('oops **** some error happened');
      // handle error
    });

为您服务

get(path: string, params: URLSearchParams = new URLSearchParams()): Observable<any> {
        console.log('sending request to ' + `${environment.api_url}${path}`);
        return this.http.get(`${environment.api_url}${path}`, { search: params })
          .catch(this.formatErrors)
          .map((res: Response) => {
            <PowerPlant[]> res.json();
        });
      }

请注意,我的映射可能是错误的,因为您没有显示返回数据的实际值。

希望这会有所帮助。

【讨论】:

  • 我已经编辑了我的帖子以显示我从服务器获取的数组
  • 好的 似乎仍然没有映射数据!当我在 allPowerPlants 方法中使用 console.log(this.powerPlants) 时,我认为它是未定义的
  • @sparkr 请检查您是否正确定义了界面。即在您的界面中,您定义id,而在数据中它是powerPlantId,您还定义了orgName,而返回的数据没有具有orgName 的属性。如果还有错误,请告诉我
  • 我用正确的字段名称更新了我的帖子!是的,我的服务中仍然没有数据!
  • 你能告诉我如何避免我的 Angular 打这么多电话吗?我想我可以将 Observable 转换为 Promise,但是如何从 Promise 中获取价值?我将这个函数称为 allPowerPlants,就像我在上面更新的帖子中看到的一样!
【解决方案2】:

好的,网上有很多关于如何处理http请求的例子,这里有很多......

通常你有一个带有 get 方法的服务永远不要使用像 GET 这样的保留词来调用你的方法 ...在你的情况下是 getAllPowerplants

在您的情况下,API 服务看起来不错(方法名称除外)

然后在组件上,你会有这样的东西

this.apiService.getAllPowerplants.subscribe(data => {
  console.log(data);
});

显然只订阅一次(ngOnInit 是个好地方)来放它

【讨论】:

  • 我想你没抓住我的意思!我只订阅了一次,但我不明白为什么多次调用后端服务器!
猜你喜欢
  • 1970-01-01
  • 2016-09-28
  • 2018-02-09
  • 2016-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
  • 2011-03-30
相关资源
最近更新 更多