Typescript,JSON:映射嵌套数组总是返回空

时间:2017-03-29 11:51:19

标签: json parsing typescript ionic2 http-get

我是打字稿的新手,并尝试从GET请求解析JSON,看起来像这样(删除了一些数据):

{  
   "currency_rate":1,
   "data":[  
     {  
        "mapIdfrom":"oslo_no",
        "refr":false,
        "duration":{  
        "total":75300,
        "return":0,
        "departure":75300
     },
     "flyTo":"STR"
    }
   ]
}

我正在获得" currency_rate"例如,但是"数据" -array是空的。

GET请求看起来像这样(只有相关部分):

[...]
api_url = 'https://api.skypicker.com/flights';
[...]
let body =  {
              flyFrom: 'OSL',
              to: 'STR',
              dateFrom: '01%252F04%252F2017',
              dateTo: '20%2F04%2F2017',
              daysInDestinationFrom: 15,
              daysInDestinationTo: 20,
              returnFrom: '01%2F04%2F2017',
              returnTo: '20%2F04%2F2017',
              typeFlight: 'oneway',
              oneforcity: 0,
              one_per_date: 0,
              passengers: 1,
              adults: 1,
              children: 0,
              infants: 0,
              flyDays: '%5B0%2C1%2C2%2C3%2C4%2C5%2C6%5D',
              onlyWorkingDays: 0,
              directFlights: 0,
              partner: 'picky',
              partner_market: 'en',
              v: 2,
              xml: 0,
              curr: 'EUR',
              locale: 'en',
              price_from: 1,
              price_to: 10000,
              dtimefrom: '00%3A00',
              dtimeto: '00%3A00',
              atimefrom: '00%3A00',
              atimeto: '00%3A00',
              returndtimefrom: '00%3A00',
              returndtimeto: '00%3A00',
              returnatimefrom: '00%3A00',
              returnatimeto: '00%3A00',
              stopoverfrom: '00%3A00',
              stopoverto: '00%3A00',
              booking_token: 'hashed%20data',
              offset: 0,
              limit: 30,
              sort: 'price',
              asc: 1
            }

let bodyString = JSON.stringify(body)

return this.http.get(`${this.api_url}?${bodyString}`)
  .map(res => <SkyPickerFlight>res.json());

模型&#34; SkyPickerFlight&#34;定义如下:

import { SkyPickerFlightData } from '../models/skyPickerFlightData';
import { Observable } from 'rxjs/Rx';

export interface SkyPickerFlightI {
  currency: string;
  data: Observable<any[]>;
}

我还尝试将data: Observable<any[]>替换为实际对象data: Observable<SkyPickerFlightData[]>,但也无法正常工作。

在这里,您可以获得完整的GET请求:

https://api.skypicker.com/flights?flyFrom=OSL&to=STR&dateFrom=01%2F04%2F2017&dateTo=20%2F04%2F2017&daysInDestinationFrom=15&daysInDestinationTo=20&returnFrom=01%2F04%2F2017&returnTo=20%2F04%2F2017&typeFlight=oneway&oneforcity=0&one_per_date=0&passengers=1&adults=1&children=0&infants=0&flyDays=%5B0%2C1%2C2%2C3%2C4%2C5%2C6%5D&onlyWorkingDays=0&onlyWeekends=0&directFlights=0&partner=picky&partner_market=en&v=2&xml=0&curr=EUR&locale=en&price_from=1&price_to=10000&dtimefrom=00%3A00&dtimeto=00%3A00&atimefrom=00%3A00&atimeto=00%3A00&returndtimefrom=00%3A00&returndtimeto=00%3A00&returnatimefrom=00%3A00&returnatimeto=00%3A00&stopoverfrom=00%3A00&stopoverto=00%3A00&booking_token=hashed%20data&offset=0&limit=30&sort=price&asc=1

我仍在调查它,但看起来GET请求使用this.http.get( $ {this.api_url}有点时髦?$ {bodyString} )实际返回:

{"connections":[],"currency":"EUR","del":0,"time":1,"search_params":{"to_type":"anywhere","flyFrom_type":"anywhere","seats":{"infants":0,"passengers":1,"adults":1,"children":0}},"ref_tasks":{},"currency_rate":1.0,"data":[],"refresh":[]}

与上述GET请求不同的结果。不确定我是否清楚。但是尝试像这样的GET请求(我将免除URLSearchParams的长定义)以Bad Gateway错误结束:

return this.http.get(this.api_url, {search: params})
  .map(res => res)

----编辑----- 在我将整个网址复制粘贴到:

后,它才有效
return this.http.get(<URL PASTED HERE>)
  .map(res => res)

仍然想知道如何以干净的方式传递参数,而不是粘贴整个网址。

3 个答案:

答案 0 :(得分:0)

你的json响应的一部分不是Observable。

尝试:

export interface SkyPickerFlightI {
  currency: string;
  data: any[];
}

您将从http获得Observable<SkyPickerFlightI>,其中包含currency_ratedata

答案 1 :(得分:0)

我不明白你想通过data: Observable<any[]>;实现什么目标。正如@suraj所说,“你的json响应的一部分不会是一个Observable”。

至于答案,我认为您不需要将响应强制转换为典型的接口。一个简单的.map(res => res.json());也可以。我假设你需要这样,但是,只是说让它变得更容易。

不确定是否存在问题?因此,您可以执行此操作并检查数据是否来自您的GET:

return Observable.create(observer => {
    this.http.get(`${this.api_url}?${bodyString}`)
      .map(res => res.json())
      .subscribe((data) => {
            console.log("Data : ", data);
            observer.next(data);
      },
      (err) => {
            console.log("Error : ", err);
            observer.error(err);
      });
});

检查以上是否记录了必要的数据。如果确实如此,那么就像在代码中那样通过类型转换再次检查。

现在,在这里,您将返回一个新的Observable到调用方法。因此,您还必须subscribe()调用方法。

答案 2 :(得分:0)

问题是GET请求。使用URLSearchParams / RequestOptions由于某种原因没有用。保持“BAD GATEWAY”错误。所以我直接在http请求中传递了url:

setlocal /?

使用下面的序列化函数(我发现该函数的另一个版本与param-values的值相混淆,所以我删除了编码)。我用它来代替'序列化(json,'')':

from itertools import groupby
from operator import itemgetter
from datetime import datetime

find_dup = {"one":[["1654","raj","425","16-02-2017"],["1654","mo","426","20-02-2017"],["1654","ss","425","20-02-2017"],["1654","vs","427","20-02-2017"],["1654","ss","425","14-02-2017"]]}

find_dup_sorted = sorted(find_dup["one"], key=lambda x: (x[0], x[2], datetime.strptime(x[3], "%d-%m-%Y")))

result = {"one": []}

for k, g in groupby(find_dup_sorted, key=itemgetter(0, 2)):
    result["one"].append(next(g))

print result

感谢您的帮助!