打字稿,JSON:映射嵌套数组总是returns为空
Typescript, JSON: Mapping nested array always returns empty
我是 typescript 的新手,正在尝试从如下所示的 GET 请求中解析 JSON(删除了一些数据):
{
"currency_rate":1,
"data":[
{
"mapIdfrom":"oslo_no",
"refr":false,
"duration":{
"total":75300,
"return":0,
"departure":75300
},
"flyTo":"STR"
}
]
}
例如,我得到 "currency_rate",但是 "data" 数组是空的。
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());
模型"SkyPickerFlight"定义如下:
import { SkyPickerFlightData } from '../models/skyPickerFlightData';
import { Observable } from 'rxjs/Rx';
export interface SkyPickerFlightI {
currency: string;
data: Observable<any[]>;
}
我也试过用 data: Observable<SkyPickerFlightData[]>
替换 data: Observable<any[]>
,实际对象,但也不起作用。
在这里你可以获得完整的 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
我仍在研究它,但看起来使用 this.http.get(
${this.api_url}?${bodyString})
实际上 [=48] 的 GET 请求有点古怪=]:
{"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)
---- 编辑 -----
在我将整个 URL 复制粘贴到:
后它起作用了
return this.http.get(<URL PASTED HERE>)
.map(res => res)
仍然想知道如何以干净的方式传递参数,而不是将整个 URL 粘贴到那里。
您的 json 响应的一部分将不是 Observable。
尝试:
export interface SkyPickerFlightI {
currency: string;
data: any[];
}
您将从 http 获得一个 Observable<SkyPickerFlightI>
,其中包含 currency_rate
和 data
我不明白你想通过 data: Observable<any[]>;
达到什么目的。正如@suraj 所说,"A section of your json response would not be an 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()
在调用方法中。
问题出在 GET 请求上。由于某种原因,使用 URLSearchParams/RequestOptions 无效。一直收到 'BAD GATEWAY' 错误。所以我直接在 http 请求中传递了 url,如下所示:
this.http.get('https://api.skypicker.com/flights?' + bodyStringSerialized)
使用下面的序列化函数(我发现这个函数的另一个版本混淆了参数值的值,所以我删除了编码)。我用了它 'serialized(json, '')':
serialize(obj, prefix) {
var str = [], p;
for(p in obj) {
if (obj.hasOwnProperty(p)) {
var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
str.push((v !== null && typeof v === "object") ?
this.serialize(v, k) :
k + "=" + v);
}
}
return str.join("&");
}
感谢您的帮助!
我是 typescript 的新手,正在尝试从如下所示的 GET 请求中解析 JSON(删除了一些数据):
{
"currency_rate":1,
"data":[
{
"mapIdfrom":"oslo_no",
"refr":false,
"duration":{
"total":75300,
"return":0,
"departure":75300
},
"flyTo":"STR"
}
]
}
例如,我得到 "currency_rate",但是 "data" 数组是空的。
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());
模型"SkyPickerFlight"定义如下:
import { SkyPickerFlightData } from '../models/skyPickerFlightData';
import { Observable } from 'rxjs/Rx';
export interface SkyPickerFlightI {
currency: string;
data: Observable<any[]>;
}
我也试过用 data: Observable<SkyPickerFlightData[]>
替换 data: Observable<any[]>
,实际对象,但也不起作用。
在这里你可以获得完整的 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
我仍在研究它,但看起来使用 this.http.get(
${this.api_url}?${bodyString})
实际上 [=48] 的 GET 请求有点古怪=]:
{"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)
---- 编辑 ----- 在我将整个 URL 复制粘贴到:
后它起作用了return this.http.get(<URL PASTED HERE>)
.map(res => res)
仍然想知道如何以干净的方式传递参数,而不是将整个 URL 粘贴到那里。
您的 json 响应的一部分将不是 Observable。
尝试:
export interface SkyPickerFlightI {
currency: string;
data: any[];
}
您将从 http 获得一个 Observable<SkyPickerFlightI>
,其中包含 currency_rate
和 data
我不明白你想通过 data: Observable<any[]>;
达到什么目的。正如@suraj 所说,"A section of your json response would not be an 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()
在调用方法中。
问题出在 GET 请求上。由于某种原因,使用 URLSearchParams/RequestOptions 无效。一直收到 'BAD GATEWAY' 错误。所以我直接在 http 请求中传递了 url,如下所示:
this.http.get('https://api.skypicker.com/flights?' + bodyStringSerialized)
使用下面的序列化函数(我发现这个函数的另一个版本混淆了参数值的值,所以我删除了编码)。我用了它 'serialized(json, '')':
serialize(obj, prefix) {
var str = [], p;
for(p in obj) {
if (obj.hasOwnProperty(p)) {
var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
str.push((v !== null && typeof v === "object") ?
this.serialize(v, k) :
k + "=" + v);
}
}
return str.join("&");
}
感谢您的帮助!